Skip to content

Conversation

@google-labs-jules
Copy link
Contributor

@google-labs-jules google-labs-jules bot commented Jan 6, 2026

Implemented DoS prevention by limiting the length of version strings in compareTo function. Also optimized the removal of 'v' prefixes to be more robust and performant. Added tests to verify these security enhancements.


PR created automatically by Jules for task 11867803423465228644 started by @srod


Summary by cubic

Prevents DoS in version comparison by rejecting inputs longer than 256 characters and makes 'v' prefix stripping robust for multiple prefixes. Invalid or overly long strings now fail-closed across all comparators; also exposes eolDate for the current major.

  • Bug Fixes
    • Enforce MAX_VERSION_LENGTH = 256 in compareTo to block oversized inputs.
    • Strip multiple leading 'v'/'V' using a charCodeAt loop.
    • Reject malformed inputs (whitespace, non-numeric segments); correctly handle "vv99.0.0"; added security tests.

Written for commit 016b5da. Summary will update on new commits.

@google-labs-jules
Copy link
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@changeset-bot
Copy link

changeset-bot bot commented Jan 6, 2026

🦋 Changeset detected

Latest commit: 016b5da

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
node-version Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2026

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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

@codecov
Copy link

codecov bot commented Jan 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (9fd192f) to head (016b5da).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #791   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         1           
  Lines           41        64   +23     
  Branches        14        28   +14     
=========================================
+ Hits            41        64   +23     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Add `MAX_VERSION_LENGTH` constant (256) to limit input length.
- Optimize `v` prefix stripping to handle multiple `v`s and avoid regex.
- Update security tests to verify DoS prevention and robust parsing.
@srod srod force-pushed the sentinel-security-fix-11867803423465228644 branch from 880700c to 131c4a3 Compare January 6, 2026 20:27
@srod srod marked this pull request as ready for review January 6, 2026 20:32
@srod
Copy link
Owner

srod commented Jan 6, 2026

@greptile

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 8 files

@greptile-apps
Copy link

greptile-apps bot commented Jan 6, 2026

Greptile Summary

Implemented DoS prevention by limiting version string length to 256 characters and hardened input validation with fail-closed behavior. Added robust 'v' prefix stripping using charCodeAt loop to handle multiple prefixes. Introduced eolDate property to expose End-of-Life dates for major versions.

  • Security Enhancements: DoS prevention via MAX_VERSION_LENGTH constant; whitespace rejection; strict numeric-only segment validation; NaN return on invalid input ensures all comparison methods fail-closed
  • Prefix Stripping: Optimized loop strips multiple 'v'/'V' prefixes using charCodeAt (118='v', 86='V')
  • New Feature: Added eolDate: Date | undefined to NodeVersion interface with proper documentation
  • Testing: Comprehensive security test suite covers edge cases including malformed inputs, long strings, and multiple prefixes
  • Issues Found:
    • Security test file uses incompatible vi.hoisted syntax causing test failures (needs fix to match src/index.test.ts pattern)
    • Leading zeros like "010.0.0" are accepted and parse as 10, may not align with strict semver expectations
    • bun.lock configVersion downgraded from 1 to 0 without explanation

Confidence Score: 4/5

  • Safe to merge after fixing test syntax; security logic is sound with fail-closed behavior
  • Strong security implementation with comprehensive validation and fail-closed design. Test file has syntax error preventing execution but doesn't affect production code. Minor style considerations around leading zeros and bun.lock change.
  • Pay attention to src/security.test.ts for the test failure fix

Important Files Changed

Filename Overview
src/index.ts Security hardening with DoS prevention and robust validation; minor style suggestion on leading zeros
src/security.test.ts Comprehensive security tests added but vi.hoisted syntax causes test failure
bun.lock configVersion downgraded from 1 to 0, needs verification

Sequence Diagram

sequenceDiagram
    participant User
    participant API as NodeVersion API
    participant compareTo as compareTo()
    participant Validation as Input Validation

    User->>API: isAtLeast("vv99.0.0")
    API->>compareTo: compareTo("vv99.0.0")
    
    compareTo->>Validation: Check whitespace & length
    Validation-->>compareTo: Valid (no trim needed, ≤256 chars)
    
    compareTo->>Validation: Strip 'v' prefixes
    Note over Validation: Loop charCodeAt check<br/>118='v', 86='V'
    Validation-->>compareTo: Stripped: "99.0.0"
    
    compareTo->>Validation: Validate segments
    Note over Validation: Check each segment<br/>non-empty & digits only
    Validation-->>compareTo: Valid segments
    
    compareTo->>compareTo: Compare version parts
    Note over compareTo: 20.0.0 < 99.0.0
    compareTo-->>API: Returns -1
    
    API->>API: Check !isNaN(-1) && -1 >= 0
    API-->>User: false
    
    Note over User,Validation: Fail-closed behavior:<br/>Invalid input → NaN → false
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

5 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@srod
Copy link
Owner

srod commented Jan 6, 2026

@greptile

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

5 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +88 to +92
for (const segment of s2) {
if (segment === "" || !/^\d+$/.test(segment)) {
return NaN;
}
}
Copy link

Choose a reason for hiding this comment

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

style: Validation checks each segment but only validates digits. Leading zeros in version segments like "010.0.0" parse as 10 (see test at src/security.test.ts:68), but this may not match semver expectations where leading zeros could be considered invalid in some contexts.

Suggested change
for (const segment of s2) {
if (segment === "" || !/^\d+$/.test(segment)) {
return NaN;
}
}
for (const segment of s2) {
if (segment === "" || !/^\d+$/.test(segment)) {
return NaN;
}
// Reject leading zeros (except "0" itself) per strict semver
if (segment.length > 1 && segment[0] === "0") {
return NaN;
}
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/index.ts
Line: 88:92

Comment:
**style:** Validation checks each segment but only validates digits. Leading zeros in version segments like `"010.0.0"` parse as `10` (see test at src/security.test.ts:68), but this may not match semver expectations where leading zeros could be considered invalid in some contexts.

```suggestion
        for (const segment of s2) {
            if (segment === "" || !/^\d+$/.test(segment)) {
                return NaN;
            }
            // Reject leading zeros (except "0" itself) per strict semver
            if (segment.length > 1 && segment[0] === "0") {
                return NaN;
            }
        }
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +5 to +12
const { mockVersion } = vi.hoisted(() => ({
mockVersion: { node: "20.0.0" },
}));

vi.mock("node:process", () => ({
versions: mockVersion,
release: {},
}));
Copy link

Choose a reason for hiding this comment

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

syntax: vi.hoisted is not available in the version of vitest used by this project (based on test failure). Use the same mocking pattern as src/index.test.ts:11-14.

Suggested change
const { mockVersion } = vi.hoisted(() => ({
mockVersion: { node: "20.0.0" },
}));
vi.mock("node:process", () => ({
versions: mockVersion,
release: {},
}));
const { mockVersion } = vi.hoisted(() => ({
mockVersion: { node: "20.0.0" },
}));
vi.mock("node:process", () => ({
versions: mockVersion,
release: {},
}));
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/security.test.ts
Line: 5:12

Comment:
**syntax:** `vi.hoisted` is not available in the version of vitest used by this project (based on test failure). Use the same mocking pattern as `src/index.test.ts:11-14`.

```suggestion
const { mockVersion } = vi.hoisted(() => ({
    mockVersion: { node: "20.0.0" },
}));

vi.mock("node:process", () => ({
    versions: mockVersion,
    release: {},
}));
```

How can I resolve this? If you propose a fix, please make it concise.

{
"lockfileVersion": 1,
"configVersion": 1,
"configVersion": 0,
Copy link

Choose a reason for hiding this comment

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

style: configVersion downgraded from 1 to 0. Verify this was intentional and doesn't affect dependency resolution.

Prompt To Fix With AI
This is a comment left during a code review.
Path: bun.lock
Line: 3:3

Comment:
**style:** `configVersion` downgraded from 1 to 0. Verify this was intentional and doesn't affect dependency resolution.

How can I resolve this? If you propose a fix, please make it concise.

@srod srod merged commit e821e92 into main Jan 6, 2026
14 checks passed
@srod srod deleted the sentinel-security-fix-11867803423465228644 branch January 6, 2026 20:50
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.

2 participants