Back to Initiative Library
Security & Compliance Medium complexity

NuGet Package Source Mapping Enforcement

✦ Sample Prompt
Add `<packageSourceMapping>` to every `nuget.config` / `NuGet.Config` so internal
packages can only resolve from the internal feed (defeats dependency confusion).

For each repository:
1. Find every `nuget.config` or `NuGet.Config` file (repo root, solution dir, or
   `src/`).
2. Preserve existing `<packageSources>` and `<packageSourceCredentials>` blocks.
3. Insert a `<packageSourceMapping>` block inside `<configuration>` that maps:
   - The `internal` feed (or whatever feed key you use) to internal package
     prefixes: `MyOrg.*`, `Internal.*` (provided per-org)
   - The `nuget.org` feed to `*` (everything else)
   Example:
     <packageSourceMapping>
       <packageSource key="internal">
         <package pattern="MyOrg.*" />
       </packageSource>
       <packageSource key="nuget.org">
         <package pattern="*" />
       </packageSource>
     </packageSourceMapping>
4. If a `<packageSourceMapping>` already exists and covers the internal prefix(es),
   skip the file. If it exists but is incomplete, merge in the missing entries
   without removing existing rules.
5. Do not modify feed URLs or credentials.

The Problem

Without package source mapping, NuGet falls back to whichever feed responds first when resolving a package. That’s the entire mechanism behind dependency confusion attacks: an attacker publishes a package on nuget.org with the same name as your internal one, and your build silently pulls the malicious version.

Microsoft’s recommended fix is to declare a `<packageSourceMapping>` block in `nuget.config` that explicitly routes each package prefix to a specific feed. The fix is well-documented but requires inventorying every internal package prefix and rolling out a consistent mapping across every .NET repo.

What Tidra Does

  1. Finds every nuget.config / NuGet.Config across repos
  2. Inserts a <packageSourceMapping> block mapping your internal prefix(es) (e.g., MyOrg.*) to the internal feed and everything else to nuget.org
  3. Preserves existing feed declarations and credentials
  4. Skips repos that already declare a complete source mapping
  5. Opens one PR per repo with a link to the supply chain hardening RFC

Before & After

diff
nuget.config
@@ -3,6 +3,14 @@
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="internal" value="https://nuget.example.com/v3/index.json" />
</packageSources>
+ <packageSourceMapping>
+ <packageSource key="internal">
+ <package pattern="MyOrg.*" />
+ </packageSource>
+ <packageSource key="nuget.org">
+ <package pattern="*" />
+ </packageSource>
+ </packageSourceMapping>
</configuration>

Customization Tips

  • Prefix patterns: Provide your internal package prefixes (e.g., MyOrg.*, Internal.*). Tidra applies them consistently.
  • Multi-feed setups: If you have separate feeds for stable vs. preview, declare both in the prompt and Tidra routes accordingly.
  • Solution-level configs: Tidra handles both repo-root and solution-level nuget.config files.

Ready to run this across your repos?

Connect your Git provider and Tidra opens pull requests in every repo that needs them.