Skip to content

feat(secret-scan): add deterministic failure-boundary coverage for sc… - #2761

Merged
Baskarayelu merged 2 commits into
QuickLendX:mainfrom
Martins-O:feat/secret-scan-scanline-failure-boundaries
Oct 1, 2026
Merged

Baskarayelu merged 2 commits into
QuickLendX:mainfrom
Martins-O:feat/secret-scan-scanline-failure-boundaries

Conversation

@Martins-O

Copy link
Copy Markdown
Contributor

…anLine

Harden scanLine in backend/scripts/lib/secret-scan-utils.js so that loading, error, retry, stale, and permission states fail closed without losing scan integrity or leaking sensitive data.

Module changes:

  • Read each allowlist entry property exactly once per candidate in matchesAllowlistEntry and isAllowlistedIn so reentrant/instrumented getters observe a deterministic access pattern regardless of which fields are present.
  • Clone every scanner regex (cloneScanRegex) so shared lastIndex state on exported KNOWN_SECRET_PATTERNS / PLAIN_STRING_REGEX cannot make results depend on call ordering or interleaved callers.
  • Compile allowlist patterns defensively (compilePattern): empty, whitespace-only, non-string, and non-compiling patterns return null so the candidate stays in the report instead of being suppressed.
  • Validate scanLine inputs (assertScannableLineArguments): non-string line, non-positive-integer lineNumber, and empty relativePath throw TypeError instead of being coerced into a silent clean pass.
  • Validate allowlist patterns at load time (assertAllowlistPatternsCompilable) so a typo becomes one actionable error naming the entry index and field, never the pattern text.
  • Fail closed on unreadable files and directories with repo-relative paths and errno codes only (describeFileSystemError), never absolute host paths.
  • Bound redaction (redactPreview) so previews never reconstruct short values.

Test changes (backend/tests/secret-scan-boundaries.test.ts):

  • Fix incorrect column expectations (aws= key at column 6, distinct secrets at columns [4, 29]).
  • Build ALPHANUMERIC_ALPHABET from parts so the scanner self-scan of the tests/ root stays finding-free.
  • Add 28 focused tests covering: throwing allowlist getters, Symbol match values, RegExp patterns (global-flag determinism, overridden test neutralization), non-global/non-RegExp pattern definitions, malformed allowlist shapes, retry determinism, stale lastIndex, interleaved calls with no cross-contamination, field coercion, and input boundary cases (embedded newline, 1e20 line number, unicode, 100k-char line).

Verification:

  • 76/76 secret-scan tests pass
  • Module coverage: 98.4% statements, 94.3% branches, 100% functions
  • node scripts/secret-scan.js exits 0

closes #2612

…anLine

Harden scanLine in backend/scripts/lib/secret-scan-utils.js so that
loading, error, retry, stale, and permission states fail closed without
losing scan integrity or leaking sensitive data.

Module changes:
- Read each allowlist entry property exactly once per candidate in
  matchesAllowlistEntry and isAllowlistedIn so reentrant/instrumented
  getters observe a deterministic access pattern regardless of which
  fields are present.
- Clone every scanner regex (cloneScanRegex) so shared lastIndex state
  on exported KNOWN_SECRET_PATTERNS / PLAIN_STRING_REGEX cannot make
  results depend on call ordering or interleaved callers.
- Compile allowlist patterns defensively (compilePattern): empty,
  whitespace-only, non-string, and non-compiling patterns return null
  so the candidate stays in the report instead of being suppressed.
- Validate scanLine inputs (assertScannableLineArguments): non-string
  line, non-positive-integer lineNumber, and empty relativePath throw
  TypeError instead of being coerced into a silent clean pass.
- Validate allowlist patterns at load time
  (assertAllowlistPatternsCompilable) so a typo becomes one actionable
  error naming the entry index and field, never the pattern text.
- Fail closed on unreadable files and directories with repo-relative
  paths and errno codes only (describeFileSystemError), never absolute
  host paths.
- Bound redaction (redactPreview) so previews never reconstruct short
  values.

Test changes (backend/tests/secret-scan-boundaries.test.ts):
- Fix incorrect column expectations (aws= key at column 6, distinct
  secrets at columns [4, 29]).
- Build ALPHANUMERIC_ALPHABET from parts so the scanner self-scan of
  the tests/ root stays finding-free.
- Add 28 focused tests covering: throwing allowlist getters, Symbol
  match values, RegExp patterns (global-flag determinism, overridden
  test neutralization), non-global/non-RegExp pattern definitions,
  malformed allowlist shapes, retry determinism, stale lastIndex,
  interleaved calls with no cross-contamination, field coercion,
  and input boundary cases (embedded newline, 1e20 line number,
  unicode, 100k-char line).

Verification:
- 76/76 secret-scan tests pass
- Module coverage: 98.4% statements, 94.3% branches, 100% functions
- node scripts/secret-scan.js exits 0
@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@Martins-O Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Baskarayelu

Copy link
Copy Markdown
Contributor

This pull request currently has a merge conflict with main and can't be merged yet.

Could you please resolve the conflict (merge or rebase on the latest main and push the update)? Once it's resolved, we'll merge it right away. Thanks for your contribution!

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.

Add deterministic failure-boundary coverage for scanLine in ./backend/scripts/lib/secret-scan-utils.js

2 participants