Install
$ agentstack add skill-tunahanaliozturk-secure-dotnet-skills-dependency-supplychain-check ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Dependency & Supply-Chain Check
Directs the agent to enumerate every NuGet dependency (direct and transitive), surface known CVEs, flag supply-chain risks (floating versions, missing lock files, unguarded package sources), and produce a prioritized remediation list with the exact commands and config changes required.
When to use
- A PR adds, upgrades, or removes a NuGet package in any .NET project or solution.
- A periodic security audit requires a point-in-time vulnerability sweep across the dependency graph.
- CI is failing on a
--locked-moderestore because the lock file is out of date or absent. - A private Azure Artifacts feed is in use alongside nuget.org and no source mapping is configured (dependency-confusion risk).
Process
- Enumerate all dependencies. Run
dotnet list package --include-transitiveon the solution or each project to capture the full dependency graph (direct + transitive). Note the SDK version and `` — some advisories are framework-specific. - Check for known vulnerabilities. Run
dotnet list package --vulnerable --include-transitive. The CLI queries the GitHub Advisory Database (via NuGet's vulnerability metadata endpoint) and reports each vulnerable package, the affected version range, the advisory URL, and severity. Treat every High/Critical advisory as a blocker; Medium advisories require a documented risk-acceptance comment or a fix. - Check maintenance health. Run
dotnet list package --deprecatedto catch packages the NuGet gallery has marked deprecated (absorbed into another package, legacy, or has a known critical bug). Rundotnet list package --outdatedto see how many major/minor versions behind each dependency is. Cross-reference heavily outdated packages against NuGet.org and the package's GitHub repo for commit activity — a package with no releases in 3+ years and no open-source maintainer is an abandonment risk. - Check supply-chain hygiene. Audit four areas in order: (a) version pinning — no floating
*or open-ended>=version specs in.csprojorDirectory.Packages.props; (b) lock file —packages.lock.jsonpresent and committed,RestoreLockedModeset in project or CI uses--locked-modeondotnet restore; (c) package source mapping —nuget.configlists a `section that maps every known package prefix to its authoritative feed, preventing a same-named private package from resolving from nuget.org (dependency confusion); (d) signed packages —nuget.config` or the NuGet audit settings require package signing from trusted publishers for critical packages. - Output a prioritized remediation list. Group findings: Critical/High CVEs → must fix before merge; Deprecated/abandoned → fix in current sprint or log a ticket; Floating versions / no lock file → fix in this PR (no merge until hygiene is clean); Source mapping gaps → fix before next private-feed onboarding. For each finding, give the exact package name, current version, required action, and the command or config snippet to apply it.
.NET / Azure checks
dotnet list package --vulnerable --include-transitive. Run against every project (or pass the.slnfile). The output shows the direct or transitive package, the version in use, and the advisory severity and URL. A transitive vulnerable package requires either upgrading the direct dependency that pulls it in, or adding an explicit `` to the fixed transitive version as an override. Never ignore a High or Critical advisory without a written risk-acceptance entry in the PR description and a linked tracking issue.dotnet list package --deprecatedand--outdated. Deprecated packages report the deprecation reason (Legacy, CriticalBugs, Other) and the recommended replacement. Outdated shows Current / Resolved / Latest columns — a package multiple major versions behind warrants a compatibility check before upgrading. Pay extra attention to packages owned by organisations that have changed hands or gone silent.- Central Package Management (
Directory.Packages.props). In multi-project solutions, all version numbers should live in a singleDirectory.Packages.propsat the repo root and individual.csprojfiles use `without aVersionattribute. This eliminates version skew across projects and makes upgrades a single-file change. When CPM is in use, apply all floating-version and pinning checks toDirectory.Packages.props(whereentries live) —.csprojfiles under CPM carry barewith no Version attribute, so they are not the right place to look. Conversely, flag any.csprojthat still carries its ownVersion` attribute when CPM is (or should be) in use, because that itself is a hygiene violation. - No floating
*versions. A `orVersion="13.*"inDirectory.Packages.props(or ain a.csproj) resolves to whatever latest version exists at restore time, making builds non-reproducible and supply-chain attacks easier. Every version specifier must be an exact pinned version (e.g.Version="13.0.3"`). - Lock files (
packages.lock.json) andRestoreLockedMode.packages.lock.json(generated bydotnet restore --use-lock-file) records the complete resolved graph including transitive dependencies and their content hashes. Commit it to source control. In CI, pass--locked-modetodotnet restore(or settruein the project /Directory.Build.props) so that any graph change that was not committed triggers a build failure rather than silently pulling a different package. This is the primary control against a "floating transitive" attack. - Package source mapping in
nuget.config. When a project uses both nuget.org and a private feed (Azure Artifacts, GitHub Packages, an internal Nexus), every package must be mapped to exactly one authoritative source. Without `, NuGet may resolve a private package name from nuget.org if an attacker publishes a higher-versioned package there (dependency confusion). Example of a correctnuget.config` mapping:
```xml
`` Private package prefixes (MyCompany.) must point exclusively at the private feed; the nuget.org catch-all ` must not match them.
- Signed-package validation. For critical infrastructure packages, add `
entries innuget.configto require repository or author signatures from known publishers. At minimum, enable NuGet audit inDirectory.Build.props: settrueso thatdotnet restoreitself surfaces advisories without a separatedotnet list packagestep; setallto extend the audit scope to transitive packages (not just direct dependencies); setlow(orhigh) to control the minimum severity that gets reported. Note that audit mode and level alone only produce warnings — to actually fail the build on vulnerabilities, promote the audit warning codes to errors viaNU1901;NU1902;NU1903;NU1904(ortrue) inDirectory.Build.props`. - Abandoned packages. A package with its last NuGet release more than 2–3 years ago, an archived or deleted GitHub repository, or one listed as unmaintained in its README carries long-term risk: CVEs will not be patched, and the package may disappear from the feed. For such packages, identify an actively maintained alternative or vendor the source.
- License compatibility. Review the licenses of new direct dependencies (and high-risk transitive ones) for compatibility with the project's own license and enterprise policy. GPL-licensed transitive dependencies can impose copyleft obligations on a commercial product. Tools such as
dotnet-project-licensesor NuGet Package Manager audit screens can automate this. Flag GPL, AGPL, or "non-commercial only" licenses as requiring legal review.
Red flags
| Signal | Why it matters | |--------|----------------| | dotnet list package --vulnerable --include-transitive reports a High or Critical severity advisory | A known, exploitable CVE is present in the deployed dependency graph; the advisory URL contains PoC or exploitation context in most cases. | | ` in Directory.Packages.props or Version="" in .csproj | Floating versions make the build non-reproducible; a malicious publisher can push a higher version to the feed and have it silently picked up on the next restore. | | packages.lock.json absent or not committed to source control | The full resolved graph is never validated; transitive dependencies can change between restores without any record or alert. | | dotnet restore in CI without --locked-mode (and no RestoreLockedMode in the project) | CI pulls whatever the registry serves today; a supply-chain compromise or accidental version bump is invisible until runtime. | | Private Azure Artifacts feed in nuget.config with no section | Any MyCompany. package can be shadow-published to nuget.org at a higher version and will be preferred by NuGet's version resolution (dependency-confusion attack). | | dotnet list package --deprecated reports a CriticalBugs deprecation reason | The NuGet gallery owner has flagged the package as having a known critical defect; the fix is the named replacement package, not a version pin. | | A key dependency (e.g. a serializer, crypto library, or JWT library) with no NuGet release in 3+ years and an archived GitHub repo | Unmaintained packages accumulate unpatched CVEs; no patch will be forthcoming. Replace or vendor the dependency. | | All packages resolve from nuget.org only — no source mapping — but the team uses an internal feed for Internal.*` packages | Indicates source mapping was never configured; any internal package name can be hijacked on nuget.org. |
Example
See [examples/dependency-supplychain-check/](../../examples/dependency-supplychain-check/).
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: tunahanaliozturk
- Source: tunahanaliozturk/secure-dotnet-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.