fix: remediate deepsec security scan findings#9
Conversation
- release.yml: close GitHub Actions script-injection vector via
attacker-controlled git tag name (CWE-78). Bind workflow context to
job-level env (TAG/REPO/COMMIT_SHA), add a fail-closed semver
tag-format gate as the first step, remove all ${{ }} interpolation
from run: blocks, quote shell expansions.
- config.ts: enforce 0o700/0o600 via explicit chmod after write in
saveConfig and clearConfig — writeFileSync/mkdirSync mode is
create-only, so a pre-existing config kept loose perms and could
leak the plaintext API key on a multi-user host.
- segments.ts: validate --filter-sets is a JSON array (matches the
documented contract and buildImportBody); add regression test.
- profiles.ts: document the intentional GET-with-body profile-search
contract so it is not "fixed" to POST (would break the Formo API).
Build (tsc), lint (eslint), and 88 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces several improvements, including documentation for the GET-with-body API contract in profiles, stricter validation for filter sets in segments, and enhanced security for configuration files by explicitly enforcing file permissions using chmodSync. A review comment suggests refactoring the filter set validation to separate JSON parsing from type checking for better clarity and consistency.
| try { | ||
| parsedFilterSets = JSON.parse(options.filterSets) | ||
| if (!Array.isArray(parsedFilterSets)) { | ||
| throw new Error('not an array') | ||
| } | ||
| } catch { | ||
| throw new Error('--filter-sets must be a valid JSON array') | ||
| } |
There was a problem hiding this comment.
For better code clarity and consistency with other parts of the codebase (like parseSearchConditions in profiles.ts), it's better to separate the JSON parsing from the type validation. This makes the control flow more explicit and avoids throwing an error just to have it immediately caught with its message discarded.
| try { | |
| parsedFilterSets = JSON.parse(options.filterSets) | |
| if (!Array.isArray(parsedFilterSets)) { | |
| throw new Error('not an array') | |
| } | |
| } catch { | |
| throw new Error('--filter-sets must be a valid JSON array') | |
| } | |
| try { | |
| parsedFilterSets = JSON.parse(options.filterSets); | |
| } catch { | |
| throw new Error('--filter-sets must be a valid JSON array'); | |
| } | |
| if (!Array.isArray(parsedFilterSets)) { | |
| throw new Error('--filter-sets must be a valid JSON array'); | |
| } |
Build (tsc), lint (eslint), and 88 tests pass.
Need help on this PR? Tag
@codesmithwith what you need.