Skip to content

fix: prototype pollution and shallow freeze in SkillFollowups.get()#558

Merged
anandgupta42 merged 1 commit intomainfrom
test/release-v0.5.14-adversarial
Mar 29, 2026
Merged

fix: prototype pollution and shallow freeze in SkillFollowups.get()#558
anandgupta42 merged 1 commit intomainfrom
test/release-v0.5.14-adversarial

Conversation

@anandgupta42
Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes 2 bugs found during v0.5.14 release adversarial testing in SkillFollowups.get():

  1. Prototype pollution: FOLLOWUPS["__proto__"] traversed Object.prototype instead of returning []. Fixed with Object.hasOwn() guard.
  2. Shallow freeze: Object.freeze() on the array didn't freeze nested suggestion objects, allowing shared state mutation across callers. Fixed with deep copy via Object.freeze({ ...s }).

Adds 52 adversarial tests covering:

  • SkillFollowups: injection attacks (__proto__, constructor, SQL, XSS, path traversal, null bytes), boundary values (100K char names, 1000 rapid calls, unicode), immutability (frozen array, frozen objects, mutation isolation), data integrity (no cycles, valid skill names, non-empty fields)
  • Locale.duration: all tier transitions (ms→s→m→h→d), days/hours fix regression tests, type confusion (NaN, Infinity, negative, MAX_SAFE_INTEGER), idempotency
  • Dispatcher.reset: hook cleanup verification, double reset, register-after-reset, concurrent reset+call, rapid reset-register cycles

Type of change

  • Bug fix
  • New feature
  • Test coverage
  • Documentation
  • Refactoring
  • Infrastructure

Issue for this PR

Closes #557

How did you verify your code works?

All 52 new adversarial tests pass:

bun test --timeout 30000 test/skill/release-v0.5.14-adversarial.test.ts
52 pass, 0 fail

Existing skill tests (97 total) still pass:

bun test --timeout 30000 test/skill/ test/tool/skill.test.ts
97 pass, 0 fail

Broader regression (altimate + util suites):

1842 pass, 423 skip, 0 fail across 95 files

Checklist

  • Tests pass locally
  • No flaky test patterns (no mock.module, no timing deps, no shared state)
  • Tests follow adversarial patterns from existing test suite
  • Marker guard passes (bun run script/upstream/analyze.ts --markers --strict)
  • Prettier passes
  • Typecheck passes

Adversarial testing for v0.5.14 release found 2 bugs:

1. **Prototype pollution:** `FOLLOWUPS["__proto__"]` traversed
   `Object.prototype` instead of returning `[]`. Fixed with
   `Object.hasOwn()` guard.

2. **Shallow freeze:** `Object.freeze()` on the array didn't freeze
   nested suggestion objects, allowing shared state mutation across
   callers. Fixed with deep copy via `Object.freeze({ ...s })`.

Includes 52 adversarial tests covering injection attacks, boundary
values, immutability, concurrency, and data integrity for
`SkillFollowups`, `Locale.duration`, and `Dispatcher.reset`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

Warning

Rate limit exceeded

@anandgupta42 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 54 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 14 minutes and 54 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5bd2272f-b7e9-43ad-80ab-b1a21ad0b060

📥 Commits

Reviewing files that changed from the base of the PR and between dbff413 and f735611.

📒 Files selected for processing (2)
  • packages/opencode/src/skill/followups.ts
  • packages/opencode/test/skill/release-v0.5.14-adversarial.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/release-v0.5.14-adversarial

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@anandgupta42 anandgupta42 merged commit d022b21 into main Mar 29, 2026
11 checks passed
@anandgupta42 anandgupta42 deleted the test/release-v0.5.14-adversarial branch March 29, 2026 03:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: prototype pollution and shallow freeze in SkillFollowups.get()

1 participant