Skip to content

fix(security): resolve infinite recursion risk in SecurityError.getSafeStack()#393

Merged
nullvariant merged 1 commit into
mainfrom
fix/security-error-infinite-recursion
Mar 29, 2026
Merged

fix(security): resolve infinite recursion risk in SecurityError.getSafeStack()#393
nullvariant merged 1 commit into
mainfrom
fix/security-error-infinite-recursion

Conversation

@nullvariant
Copy link
Copy Markdown
Owner

Summary

  • Fix potential infinite recursion in SecurityError.getSafeStack() by storing raw stack in a private field before overriding the stack getter via Object.defineProperty
  • Delegate path sanitization to pathSanitizer.sanitizePath() instead of maintaining 12 independent regex patterns (DRY)
  • Strip stack from originalError in createSystemError/wrapError to prevent unsanitized path leakage via getInternalDetails()
  • Return frozen shallow copy from getInternalDetails() to prevent external mutation of audit log data
  • Add recursion safety test, stack stripping tests, frozen copy test, and isFatalError unit tests

Test plan

  • All existing tests pass
  • Statement coverage remains at 100%
  • ESLint clean
  • TypeScript compiles without errors
  • New recursion test verifies error.stack access does not throw RangeError
  • Stack stripping tests verify originalError.stack is not carried over
  • Frozen copy test verifies getInternalDetails() returns immutable object
  • isFatalError tests cover all ErrorCategory variants and non-Error values

🤖 Generated with Claude Code

@nullvariant-mimi
Copy link
Copy Markdown
Contributor

nullvariant-mimi Bot commented Mar 29, 2026

🐰 Mimi's Validation Report ✅

All checks are looking good! Great job! 🎉

⏳ Some checks are still running. I will keep watching!


バリデーターを通してくださいね

This report was carefully prepared by nullvariant-mimi[bot]

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 29, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA d69fd2f.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@nullvariant-slow
Copy link
Copy Markdown
Contributor

nullvariant-slow Bot commented Mar 29, 2026

🦥 Slow's Code Review 😩

...yawn... Do I really have to review this?

⚠️ TOO LONG... I can barely keep my eyes open reading these:

File Lines

| extensions/git-id-switcher/src/core/errors.ts | 400 |
| extensions/git-id-switcher/src/test/errors.test.ts | 461 |

Split it up... reading long files is exhausting.


働きたくないでござる

This review was reluctantly filed by nullvariant-slow[bot]

@nullvariant-ciel
Copy link
Copy Markdown
Contributor

nullvariant-ciel Bot commented Mar 29, 2026

🕊️ Ciel's Mediation 🌤️

*~~ floating down from the clouds ~~ The zoo seems a bit noisy today...*

2 zoo members have reviewed this PR.

Zoo Member Status
🦥 Slow Commented
🐰 Mimi Commented

⚖️ The zoo has mixed opinions. Some are concerned, some are fine with it. Please review each comment carefully and make the final call.


まあまあ、ほどほどに。

This mediation was peacefully delivered by nullvariant-ciel[bot]

…getSafeStack()

- Store raw stack in private field before overriding stack getter
  to break the circular reference between Object.defineProperty
  getter and getSafeStack() that relied on V8-specific behavior
- Delegate path sanitization to pathSanitizer.sanitizePath() (DRY)
- Strip stack from originalError in createSystemError/wrapError
  to prevent unsanitized path leakage via getInternalDetails()
- Return frozen shallow copy from getInternalDetails() to prevent
  external mutation of audit log data
- Add recursion safety test, stack stripping tests, frozen copy
  test, and isFatalError unit tests

🖥️ IDE: [Cursor](https://cursor.sh)
🔌 Extension: [Claude Code](https://claude.ai/download)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Model-Raw: claude-opus-4-6
@nullvariant nullvariant force-pushed the fix/security-error-infinite-recursion branch from e18a462 to d69fd2f Compare March 29, 2026 10:34
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonarqubecloud
Copy link
Copy Markdown

@nullvariant nullvariant merged commit 9856ef2 into main Mar 29, 2026
29 checks passed
@nullvariant nullvariant deleted the fix/security-error-infinite-recursion branch March 29, 2026 10:37
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