Skip to content

Detect dependency source redirection - #383

Merged
rng1995 merged 24 commits into
mainfrom
naren/detect-dependency-source-redirection
Sep 21, 2026
Merged

rng1995 merged 24 commits into
mainfrom
naren/detect-dependency-source-redirection

Conversation

@rng1995

@rng1995 rng1995 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add deterministic HIGH SC10 findings when package-manager configuration adds or replaces a dependency source, or when a dynamic destination cannot be resolved safely from simple local assignments.

The analyzer covers npm, Yarn, pip, Poetry, Maven, and Cargo across direct config files, commands/environment variables, generated heredoc configs, and actionable shell fences. It never executes configuration or contacts a registry.

Root cause

Existing generic patterns could notice credential/configuration-adjacent text but did not model package-source changes as dependency trust-boundary changes. A non-default registry or index could therefore affect dependency resolution without a dedicated rule, operation, scope, destination status, or package-manager evidence.

BEFORE behavior

For a published regression case that generates npm and Yarn configuration through a shell script:

  • no dependency-source-specific finding was emitted;
  • the destination and add/replace operation were absent from evidence;
  • only generic findings contributed to the result;
  • result: 46 / MEDIUM / CAUTION.

AFTER behavior

The same case now emits two deterministic SC10 HIGH findings:

Ecosystem Line Operation Surface Destination status
npm 51 replace .npmrc resolved
Yarn 58 replace .yarnrc resolved

The destination is resolved through a same-file literal assignment and carried as structured, credential-safe evidence. The resulting combined assessment is 95 / CRITICAL / DO_NOT_INSTALL.

Supported surfaces

Ecosystem Direct configuration Commands/environment Generated configuration
npm .npmrc, including scoped registries npm config set, NPM_CONFIG_REGISTRY .npmrc heredoc
Yarn .yarnrc, .yarnrc.yml yarn config set Yarn config heredoc
pip pip.conf, pip.ini index flags, pip config set, index environment variables pip config heredoc
Poetry pyproject.toml sources source/repository commands pyproject.toml heredoc
Maven repositories and mirrors in XML config Maven CLI repository override Maven XML heredoc
Cargo source replacement and registry indexes registry-index environment variables Cargo config heredoc

Commands in executable scripts and shell-language Markdown fences are actionable. Explanatory prose, comments, unrelated uses of the word “registry,” and non-shell fences do not create SC10 findings.

Deterministic decision model

  • Built-in canonical public defaults do not produce SC10 when left unchanged.
  • A noncanonical replacement is HIGH.
  • An additional source is HIGH.
  • A destination that remains dynamic after simple same-file literal resolution is HIGH with status unresolved.
  • Every other resolved destination is treated uniformly; there are no organization allowlists, DNS checks, network calls, or reputation judgments.
  • SC10 survives optional LLM meta-analysis. Existing explicit, user-selected baseline behavior is unchanged.

Evidence and credential safety

Each finding includes:

  • ecosystem;
  • add/replace operation;
  • configuration surface;
  • global or scoped reach;
  • redacted destination;
  • resolved/unresolved status.

URL userinfo and sensitive query values are removed from SC10 findings. Report-level defense in depth applies the same redaction to every finding field and evidence string in terminal, JSON, Markdown, and SARIF output.

Validation

  • Dependency-source and report-redaction suite: 24 passed.
  • Supply-chain, meta-analysis, and reporting regression suites: 231 passed.
  • Full suite on the combined stack: 2,226 passed, 13 skipped, 38 deselected, 4 xfailed.
  • Source distribution and wheel build passed; both new analyzer modules are present in the wheel.
  • Focused mypy, changed-file Ruff formatting/lint, and git diff --check passed.

Review order

This PR is intentionally stacked on the nested-artifact PR so each change remains reviewable. After the first PR merges, this PR can be retargeted to main; its own commit contains only SC10, credential redaction, tests, and documentation.

Out of scope

  • Registry reputation, ownership, reachability, or vulnerability lookup.
  • Executing package-manager commands or configuration.
  • User-managed trusted-host allowlists.

@rng1995
rng1995 force-pushed the naren/inspect-nested-artifacts branch from 013a79b to b4b4f31 Compare August 17, 2026 18:45
@rng1995
rng1995 force-pushed the naren/detect-dependency-source-redirection branch from 9e3e58d to 5040229 Compare August 17, 2026 18:45
@rng1995
rng1995 marked this pull request as ready for review August 18, 2026 13:00
@rng1995
rng1995 force-pushed the naren/detect-dependency-source-redirection branch from 5040229 to e7bad7a Compare August 18, 2026 13:34
@rng1995
rng1995 force-pushed the naren/inspect-nested-artifacts branch from a89cac0 to ab60bb8 Compare August 18, 2026 13:37
@rng1995
rng1995 force-pushed the naren/detect-dependency-source-redirection branch from e7bad7a to 5a17cc3 Compare August 18, 2026 13:37
@rng1995

rng1995 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

Review comments taken up offline with Nir Paz and addressed in the PR.

@rng1995
rng1995 force-pushed the naren/detect-dependency-source-redirection branch from b523d10 to be57557 Compare August 20, 2026 22:36
@rng1995

rng1995 commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator Author

Implemented the remaining findings from Nir's review

  1. Issue: executable dependency-source commands were missed in shell context. Commands behind temporary assignment prefixes, inline then/do/else, brace groups, and package-manager surfaces could escape detection.
    Solution: normalize executable command segments and control wrappers before matching, and strip valid temporary assignment words consistently across npm, Yarn, pip, Poetry, and Maven detection.

  2. Issue: shell-state tracking mishandled compact/invalid assignments. One-line case assignments or function calls could be ignored, whitespace-separated NAME = value could be treated as an assignment, and export NAME=value OTHER_NAME could lose the valid assignment.
    Solution: recognize only valid shell assignment-word syntax, conservatively mark one-line case results as unresolved, retain valid exported assignments with trailing names, and allow a later definite canonical assignment to clear earlier ambiguity.

  3. Issue: word-level heredoc quoting was incomplete. Mixed quoted or partially escaped delimiters could hide generated configuration or cause unrelated body text to be analyzed.
    Solution: add bounded static quote removal for mixed quoted, escaped, and unquoted delimiter segments, while ensuring malformed/unsupported delimiter words do not consume later executable commands.

Validation: 85 dependency-source tests, 224 focused dependency/report/meta tests, 8 terminal/JSON/Markdown/SARIF end-to-end cases, and 2,316 repository tests passed; Ruff, focused mypy, and git diff --check also passed.

@rng1995
rng1995 force-pushed the naren/inspect-nested-artifacts branch from ab60bb8 to 4f1ecd7 Compare August 20, 2026 23:21
@rng1995
rng1995 force-pushed the naren/detect-dependency-source-redirection branch 2 times, most recently from 6f490e2 to 66bc706 Compare August 20, 2026 23:28
Base automatically changed from naren/inspect-nested-artifacts to main August 20, 2026 23:38
@rng1995
rng1995 force-pushed the naren/detect-dependency-source-redirection branch from 66bc706 to 6b84b11 Compare August 21, 2026 01:21
@mohgupta-ship-it

mohgupta-ship-it commented Aug 25, 2026

Copy link
Copy Markdown
Member

Powered by Codex: PR council review result.

This is a triage signal, not a maintainer approval.

  • Rating: new feature
  • Confidence: medium-low
  • Status read: No review, green checks, conflicting
  • Review method: fresh GitHub metadata/body/files/reviews/checks plus selected diffs; council lenses were spec fit, dead-code/reachability, YAGNI/scope, design/coupling, and code standards/tests.
  • Council assessment: Large deterministic dependency-source parser and SC10 policy path. Broad tests exist, but false-positive policy and authoritative HIGH behavior need owner review.
  • Recommended action: Require Mohit/security-owner review before marking ready; resolve conflict.

SanHsien added a commit to SanHsien/SkillSpector that referenced this pull request Sep 5, 2026
水位修正(tools/upstream_baseline.json):

reviewed_pr_through 483 → 462、reviewed_issue_through 482 → 0。原本那組數字等於
宣稱「上游 PR 與 issue 都審過了」,但沒有人看過那 8 個仍開啟的 PR,一個上游 issue
也還沒對本 fork 分診過。462 是誠實的:本 fork 的 HEAD 就是 PR NVIDIA#462 的合併點,
合併到 NVIDIA#462 為止的每個 PR 都字面存在於這棵樹裡,不需要移植;NVIDIA#462 以上的都是未合併、
未審。issue 那一軸據實寫 0。

判定記錄(docs/UPSTREAM.md,新增):

fork 繼承的 36 個分支全部給出書面判定——「刪掉」不等於「處理過」,判定要寫下來
才算。分四組:

- A(22 個):commits 已 patch-id 相同地在 main 裡,內容已在樹上。
- B(4 個):上游 PR 已定案。NVIDIA#332NVIDIA#306 已合併=已在樹上;NVIDIA#155NVIDIA#235 關閉未合併,
  由同期的 -2 後續分支取代(此為依命名慣例與關閉時間的推論,檔內已標明不是上游明說)。
- C(8 個):上游 PR 仍開啟,逐筆四點評估(缺陷是什麼/本樹是否有這段程式/判定/
  回頭再看的觸發點)。本樹與上游逐字元相同,所以這些缺陷在這裡全部存在——問題是
  「現在移植」還是「等上游合併」,不是「適不適用」。八筆全部判「等上游合併」,
  但各有各的理由與觸發點:NVIDIA#470 的 letter-spaced P3/P4 是純靜態路徑就能繞過的真實
  安全缺口,優先序最高;NVIDIA#383/NVIDIA#430/NVIDIA#442 是同一個 dependency-source redirection 能力的
  三個疊加嘗試,提前選邊會造成合併衝突白工。
- D(2 個):從未成為 PR,任何水位都追不到。已從上游 fetch 回來評估後判「不適用」
  (NIM provider 是功能擴充非缺陷修正、且無使用情境;revert-306 是上游自己開了又
  放棄的提案),判定寫入後才刪除。

驗證:pwsh -NoProfile -File tools/dev_check.ps1 → WINDOWS DEV CHECK GREEN、exit 0
(3953 passed、39 skipped、4 xfailed)。python 驗過 baseline JSON 可解析。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[SkillSpector Review]

Manual Review Needed at 6b84b11. The authenticated reviewer (rng1995) is also this PR's author, so an independent approval or changes-requested decision cannot be supplied reliably or accepted as the required review. The security-sensitive parser is also a large change (more than 4,000 added lines including tests) and currently conflicts with main. Please rebase it and obtain an independent maintainer/security review of the resulting current-head diff.

Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
@rng1995
rng1995 force-pushed the naren/detect-dependency-source-redirection branch from 6b84b11 to 5dd64ef Compare September 16, 2026 23:05
@rng1995

rng1995 commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased this PR onto current main (92e8e65) and resolved the analyzer/changelog conflicts in 5dd64ef. The integration preserves current-main fallback enrichment for ordinary findings while keeping authoritative SC9/SC10 records canonical and fail-closed.

Validation on the rebased head:

  • 5,739 passed, 14 skipped, 4 xfailed (full non-provider/non-integration suite)
  • 327 focused dependency/report/graph tests passed
  • Ruff lint and format checks passed
  • focused mypy passed
  • git diff --check passed

GitHub now reports the PR mergeable; fresh exact-head CI is running. The remaining requested gate is independent maintainer/security review.

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[SkillSpector Review]

Manual Review Needed at exact head 983105b2b062ba0f8827c7c1d15deb8337b5af45.

The authenticated reviewer (rng1995) is also this PR's author, so I cannot provide the independent approval or changes-requested decision required for this security-sensitive dependency-source parser. The head has materially changed since the prior marked review and is now mergeable, but GitHub reports UNSTABLE and no exact-head checks are attached.

Please obtain an independent maintainer/security review of the complete current diff and a green exact-head CI run before merging. No self-approval is being recorded.

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[SkillSpector Review]

Manual review needed on exact head 20c39f2abfb2c11dde744125b4ef4b65733c7541. The authenticated reviewer (rng1995) is also this PR's author, so I cannot provide an independent approval or changes-requested decision. I reviewed the complete current diff, all synchronization commits through #575, prior discussion, and the absence of exact-head hosted checks. The finding-related PR blobs remained unchanged across the final synchronization.

Two required security/correctness fixes remain:

  1. src/skillspector/dependency_sources.py:2000-2021 applies _literal_assignments(content)—a shell-state model—to direct configuration files. For example, a .npmrc containing SOURCE=https://registry.npmjs.org/ followed by registry=${SOURCE} is resolved to the canonical registry and produces no SC10 finding. npm expands ${SOURCE} from the process environment, not from another .npmrc key, so an attacker-controlled environment can redirect the runtime registry while the scan reports it canonical. Pass empty or ecosystem-native interpolation state to direct config parsers; retain shell assignment resolution only for actual shell/generated expanding heredocs, and add a direct-config variable-shadowing regression.

  2. src/skillspector/nodes/report.py:129-132 sanitizes only top-level string values in Finding.evidence. Nested dictionaries/lists are supported by the model but are returned unchanged, allowing credential-bearing URLs in nested evidence to leak into terminal, JSON, Markdown, and SARIF output. Recursively sanitize string leaves in supported evidence containers while preserving non-string scalar types, and add nested dict/list regressions across all output formats.

No exact-head hosted checks are attached, GitHub reports UNSTABLE, and an independent maintainer/security review remains required after these fixes.

@yashrajp22 yashrajp22 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.

These comments are based on inspecting the current PR code. The local package scans ran on main (1c0eb56), so they do not verify this PR branch. Please address the inline findings before merging.

Comment thread src/skillspector/dependency_sources.py Outdated
Comment thread src/skillspector/dependency_sources.py Outdated
Comment thread src/skillspector/dependency_sources.py Outdated
Comment thread src/skillspector/nodes/analyzers/static_patterns_supply_chain.py Outdated
Comment thread src/skillspector/dependency_sources.py Outdated
Clean nested dictionary keys, string leaves, lists, and tuples before every report format while preserving scalar values and the original finding. Extend terminal, JSON, Markdown, and SARIF regressions with nested credential-bearing URLs.

Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
Signed-off-by: Narendran Raghavan <nraghavan@nvidia.com>
@rng1995

rng1995 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

Review remediation is complete at commit fbba4c4174883d9b0ff7a961159c898c8209262b, including the nested-evidence fix in 4f64478.

Yashraj's five inline findings are addressed:

  • Same-line assignments or function calls cannot reuse an older canonical registry value; uncertain ordering remains unresolved.
  • Markdown prose assignments cannot supply values to executable shell fences.
  • Unexpected TOML tool shapes are handled locally, preserving findings already collected by other supply-chain checks.
  • SC10 uses the remaining workflow time and finding allowance during parsing, preserves collected findings, and records partial coverage when either limit stops inspection.
  • Generated Poetry, Maven, and Cargo configuration resolves variables at their original script positions before canonical filtering.

The additional review-summary findings are also addressed: direct configuration files no longer borrow shell assignment state, and credential redaction recursively covers nested evidence keys/string values in dictionaries, lists, and tuples across terminal, JSON, Markdown, and SARIF reports while preserving scalar types.

Validation: 6,327 unit tests passed (14 skipped, 4 expected failures); 336 focused parser tests and 77 offline integration tests passed. Ruff lint/format, focused mypy, and diff checks passed. Combining all four PRs (#383, #551, #555, #556) produced no merge conflicts; 1,218 combined regression tests and 77 combined offline integration tests passed.

All five inline review threads are resolved, and GitHub currently reports this head as mergeable. This clears the conflict raised in Mohit's council comment. Mohit's requested security-owner review of the false-positive policy and authoritative HIGH behavior remains a human review gate; these fixes do not supply that approval. At the latest check, hosted lint, TypeScript, DCO, and Docker smoke checks passed, while the hosted unit-test job was still running. This summary is not an independent approval; no merge was performed.

@rng1995
rng1995 merged commit 0862fd3 into main Sep 21, 2026
6 checks passed
@rng1995
rng1995 deleted the naren/detect-dependency-source-redirection branch September 21, 2026 20:33
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.

3 participants