Skip to content

fix(security): align SSRF denylists and reject endpoint userinfo - #7764

Closed
Ayush7614 wants to merge 3 commits into
NVIDIA:mainfrom
Ayush7614:fix/ssrf-denylist-parity-userinfo
Closed

fix(security): align SSRF denylists and reject endpoint userinfo#7764
Ayush7614 wants to merge 3 commits into
NVIDIA:mainfrom
Ayush7614:fix/ssrf-denylist-parity-userinfo

Conversation

@Ayush7614

@Ayush7614 Ayush7614 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Inference SSRF used private-networks.yaml while MCP used a harder-coded denylist, so special-purpose IPs and the metadata hostname that MCP already rejects could still pass endpoint validation. Plugin SSRF also accepted URL userinfo that CLI onboard and inference set reject. This change aligns the shared YAML denylist with MCP and rejects credentialed endpoint URLs in plugin validation.

Changes

  • Extended nemoclaw-blueprint/private-networks.yaml with MCP-parity blocks: AS112 / AMT / 6to4 anycast IPv4 ranges, ::/96, broader 2001::/23, AS112 / documentation / SRv6 / site-local IPv6 ranges, and the reserved metadata name.
  • Rejected username/password userinfo in nemoclaw/src/blueprint/ssrf.ts with the same credentials-in-URL contract used by onboard and inference set.
  • Updated package-contract SSRF boundary vectors and added MCP ↔ isPrivateHostname parity coverage in test/mcp-url-target.test.ts.
  • Updated plugin SSRF tests to assert credentialed URLs fail closed.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: Tightens existing SSRF rejection behavior; no new user-facing configure or operate docs surface.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: Awaiting maintainer security review on this PR.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: No docs/ pages changed. Change hardens existing private-network and endpoint URL validation; users already cannot point inference at private or credentialed endpoints under CLI paths.
  • Agent: Cursor

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: npx vitest run --project package-contract test/package-contract/ssrf-parity.test.ts → 214 passed; npx vitest run test/mcp-url-target.test.ts → 32 passed; npx vitest run --project plugin nemoclaw/src/blueprint/ssrf.test.ts → 101 passed; CLI and plugin builds for parity artifacts passed.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Ayush7614 ayushknj3@gmail.com

Summary by CodeRabbit

  • Security Improvements
    • Endpoint URLs containing usernames or passwords are now rejected immediately.
    • Expanded SSRF private-network protection by adding/additionally covering reserved IPv4 and IPv6 ranges.
    • Added a new cloud metadata hostname alias (e.g., metadata / instance.metadata) and ensured metadata.example.com remains allowed.
    • Updated MCP URL target filtering with an additional special-purpose IPv6 denylist entry.
  • Bug Fixes
    • Improved parity between SSRF/private-hostname filtering at CIDR boundaries.
  • Tests
    • Expanded SSRF and MCP/private-network parity test coverage for the updated ranges and metadata cases.

@copy-pr-bot

copy-pr-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5ca608f5-da55-431a-b149-4c787cc599a7

📥 Commits

Reviewing files that changed from the base of the PR and between cd058dc and a780237.

📒 Files selected for processing (5)
  • nemoclaw-blueprint/private-networks.yaml
  • nemoclaw/src/blueprint/ssrf.test.ts
  • src/lib/security/mcp-url-target.ts
  • test/mcp-url-target.test.ts
  • test/package-contract/ssrf-parity.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/mcp-url-target.test.ts
  • nemoclaw/src/blueprint/ssrf.test.ts
  • nemoclaw-blueprint/private-networks.yaml
  • test/package-contract/ssrf-parity.test.ts

📝 Walkthrough

Walkthrough

Expanded SSRF blocklists with additional IPv4/IPv6 prefixes and metadata hostnames, added parity coverage, and changed endpoint validation to reject URLs containing credentials.

Changes

SSRF protection

Layer / File(s) Summary
Special-purpose denylist coverage
nemoclaw-blueprint/private-networks.yaml, nemoclaw/src/blueprint/private-networks.ts, src/lib/private-networks.ts, test/package-contract/ssrf-parity.test.ts
Added IPv4/IPv6 special-purpose prefixes and the metadata hostname, updated documentation, and expanded CIDR and hostname parity vectors.
Endpoint credential rejection
nemoclaw/src/blueprint/ssrf.ts, nemoclaw/src/blueprint/ssrf.test.ts
validateEndpointUrl now rejects URLs containing usernames or passwords for HTTP and HTTPS.
MCP denylist parity
src/lib/security/mcp-url-target.ts, test/mcp-url-target.test.ts
Added the dummy IPv6 prefix to the MCP denylist and verified denied IPs and metadata hostnames are also classified as private hostnames.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: area: security, security, bug-fix

Suggested reviewers: brandonpelfrey

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the two main changes: SSRF denylist alignment and rejecting endpoint userinfo credentials.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nemoclaw/src/blueprint/ssrf.test.ts`:
- Around line 409-415: Add username-only and password-only credential URL cases
to the validateEndpointUrl tests, alongside the existing userinfo case, and
assert each rejection message excludes the supplied credential values while
retaining the credentials rejection expectation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f02291e7-4980-4623-aa73-8ff027afbfb7

📥 Commits

Reviewing files that changed from the base of the PR and between c4c020c and 41680f0.

📒 Files selected for processing (7)
  • nemoclaw-blueprint/private-networks.yaml
  • nemoclaw/src/blueprint/private-networks.ts
  • nemoclaw/src/blueprint/ssrf.test.ts
  • nemoclaw/src/blueprint/ssrf.ts
  • src/lib/private-networks.ts
  • test/mcp-url-target.test.ts
  • test/package-contract/ssrf-parity.test.ts

Comment thread nemoclaw/src/blueprint/ssrf.test.ts Outdated
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized E2E selections differ; severity counts match.

Nemotron output stays in workflow artifacts and does not change the assessment above.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-inference, full-e2e, hermes-e2e, security-posture, inference-routing, network-policy

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@Ayush7614

Copy link
Copy Markdown
Contributor Author

Addressed the CodeRabbit / PR Review Advisor warning: added username-only and password-only userinfo cases, and asserted rejection messages do not echo the supplied secret values.

Extend private-networks.yaml to the special-purpose ranges MCP already
blocks, and reject credentialed endpoint URLs in plugin SSRF validation
so inference and MCP share one host-safety contract.

Signed-off-by: Ayush7614 <ayushknj3@gmail.com>
Reject both credential halves and assert error messages do not echo
the supplied secret values.

Signed-off-by: Ayush7614 <ayushknj3@gmail.com>
@Ayush7614
Ayush7614 force-pushed the fix/ssrf-denylist-parity-userinfo branch from 64b2731 to b24b12d Compare July 28, 2026 21:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nemoclaw-blueprint/private-networks.yaml`:
- Around line 115-116: The IPv6 block list is missing the non-forwardable Dummy
IPv6 Prefix 100:0:0:1::/64. Add this prefix to the YAML-backed BlockList
alongside the existing special-purpose IPv6 entries, and add matching boundary
test vectors in ssrf-parity.test.ts covering addresses inside and outside the
prefix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: df2b6880-d07a-4eb6-9139-2a64dca37e26

📥 Commits

Reviewing files that changed from the base of the PR and between 64b2731 and b24b12d.

📒 Files selected for processing (7)
  • nemoclaw-blueprint/private-networks.yaml
  • nemoclaw/src/blueprint/private-networks.ts
  • nemoclaw/src/blueprint/ssrf.test.ts
  • nemoclaw/src/blueprint/ssrf.ts
  • src/lib/private-networks.ts
  • test/mcp-url-target.test.ts
  • test/package-contract/ssrf-parity.test.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • nemoclaw/src/blueprint/private-networks.ts
  • nemoclaw/src/blueprint/ssrf.ts
  • src/lib/private-networks.ts
  • nemoclaw/src/blueprint/ssrf.test.ts
  • test/mcp-url-target.test.ts

Comment thread nemoclaw-blueprint/private-networks.yaml
@Ayush7614
Ayush7614 force-pushed the fix/ssrf-denylist-parity-userinfo branch from b24b12d to cd058dc Compare July 28, 2026 22:05
…ject

Add IANA 100:0:0:1::/64 to the shared SSRF denylist and MCP target
filter, and confirm credentialed endpoint URLs fail before DNS lookup.

Signed-off-by: Ayush7614 <ayushknj3@gmail.com>
@wscurran wscurran added area: security Security controls, permissions, secrets, or hardening bug-fix PR fixes a bug or regression labels Jul 28, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for the PR. This aligns SSRF denylists across inference, MCP, and plugin validation and rejects credentialed endpoint URLs. Maintainers will review the denylist extensions, userinfo rejection, and test coverage.

@apurvvkumaria apurvvkumaria self-assigned this Aug 4, 2026

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed commit a7802373c. The SSRF changes fail closed before DNS resolution, do not echo URL credentials, align the YAML-backed CLI/plugin rules with MCP special-purpose ranges, and include boundary, parity, and credential-redaction tests. Security categories: PASS for secrets, input validation, authentication/authorization, dependencies, error handling/logging, cryptography, configuration, security tests, and system security. I found no vulnerability in the changed validation logic.

Contributor compliance blocks this PR. GitHub reports commits 280840632, cd058dcf9, and a7802373c as unsigned rather than Verified. Maintainers must not repair contributor signature history. Replace the branch with compliant Verified commits; if published history cannot be replaced, open a new branch and PR. The replacement must also include a documentation-writer receipt for its final commit and current required CI/E2E evidence. I am not updating this branch from main because that would not correct the three noncompliant commits.

@github-actions github-actions Bot added v0.0.103 and removed v0.0.102 labels Aug 4, 2026
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

The merge gate cannot pass because three commits do not appear as Verified in GitHub. Repository policy requires every contributor commit to appear as Verified. Maintainers cannot amend, sign, or force-push contributor history. Please replace the branch history with contributor-created, verified commits. After that update, maintainers can rerun the required gates and continue review.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Closing in favor of #8321.

The replacement preserves Ayush7614 as the author of all three contributor commits and reproduces the same source-and-test patch content, confirmed by the matching stable patch ID 9b95630b59f9003ea58ab702f24bef44b39eb8e8. It rebuilds that history on current main with GitHub-verified commits, adds the required user-facing documentation, and records a clean nine-category security review.

The replacement is assigned to @apurvvkumaria and retains the v0.0.103, area: security, and bug-fix labels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: security Security controls, permissions, secrets, or hardening bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants