Skip to content

fix(security): the desktop code scanning alerts - #41

Merged
DarrellVS merged 1 commit into
devfrom
24-codeql-desktop
Sep 22, 2026
Merged

DarrellVS merged 1 commit into
devfrom
24-codeql-desktop

Conversation

@DarrellVS

Copy link
Copy Markdown
Owner

Closes #24. Code scanning alerts 4, 5, 7, 8, 9, 15.

Path injection (alerts 7, 8, 9)

MoveClipToGameAction joined targetGame onto the videos root, so ..\..\Somewhere moved the recording outside the library. Now:

  • services/gameFolder.ts refuses separators, drive colon, control characters, a leading dot (the scan would never see the clip again), a trailing dot or space, and Windows device names. The route answers 400 with the reason.
  • The action also checks the resolved folder sits directly inside the root.
  • Refused rather than cleaned: this is a typed name, and filing a clip under a different spelling would be a surprise.

Regex injection (alert 15)

Compiling the user's own expression is the feature, so it is not escaped. Refused now: a quantified group that already contains a quantifier ((a+)+), and anything over 200 characters. tagPatternProblem in src/shared is used by both the route and the DTO. All 34 rules in the real library pass (checked read-only). Saved rules are not touched.

This alert will likely stay open, because CodeQL flags any new RegExp(userInput). Once merged I will dismiss it as won't fix, pointing at this PR.

Polynomial regex (alerts 4, 5)

/^'+|'+$/ (search tokeniser) and /\.+$/ (export name) replaced with a linear utils/trimChar.ts; a test holds it under 50 ms on 200,000 dots.

Gates

  • tests/unit/main/codeScanning.spec.ts, 38 cases.
  • npm run check: 681 tests.

🤖 Generated with Claude Code

Closes #24.

**A game name could move a recording out of the library.**
`MoveClipToGameAction` joined whatever came in as `targetGame` onto the
videos root, so `..\..\Somewhere` was a folder outside it and the clip was
renamed there. `services/gameFolder.ts` refuses a name holding a separator,
a drive colon, a control character, a leading dot (the scan would never
see the clip again), a trailing dot or space (Windows drops them), or a
device name; the route answers 400 with the reason, and the action checks
the resolved folder sits directly inside the root anyway, because one
guard is a single point of failure on the line that moves a recording.
Refused rather than cleaned, unlike `safeName`: this is a name somebody
typed, and filing their clip under a different spelling is a surprise.

**A tag rule could hang the library.** Compiling a regular expression the
user wrote is the feature, so it is not escaped. What is refused now is
the shape that backtracks without end, a quantified group that already
contains a quantifier (`(a+)+`), plus anything over 200 characters.
`tagPatternProblem` in `src/shared` is the one answer the route and the
DTO both use. The 34 rules in the real library all pass (checked read
only). Rules already saved are not touched.

**Two linear trims for two quadratic ones.** `/^'+|'+$/` in the search
tokeniser and `/\.+$/` on an export's name retry from every position of a
long run that does not end the string. `utils/trimChar.ts` is a loop; a
test holds it under 50 ms on 200,000 dots.

`tests/unit/main/codeScanning.spec.ts`, 38 cases. `npm run check` green.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@DarrellVS DarrellVS added this to the 3.5.0 milestone Sep 22, 2026
@DarrellVS DarrellVS added bug Something isn't working security Code scanning and hardening labels Sep 22, 2026
@DarrellVS DarrellVS self-assigned this Sep 22, 2026
@DarrellVS
DarrellVS merged commit f27d882 into dev Sep 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working security Code scanning and hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant