feat: Verify npm tokens against custom registry URLs from .npmrc context#4899
feat: Verify npm tokens against custom registry URLs from .npmrc context#4899jainlakshya wants to merge 7 commits intotrufflesecurity:mainfrom
Conversation
Implements GitHub issue trufflesecurity#1455 Modified npm token detectors (v1 and v2) to extract and verify against custom registry URLs when found in .npmrc format, instead of always using registry.npmjs.org. Changes: - Added regex to extract registry URLs from .npmrc format (//registry-url/:_authToken=token) - Modified verification to try custom registries first - Falls back to registry.npmjs.org if no custom registry found - Added registry URL to AnalysisInfo when verified - Added comprehensive tests for URL extraction and building Supports enterprise registries like Nexus, Artifactory, and others. Example formats now supported: //artifactory.example.com/:_authToken=token //nexus.example.com/repository/npm-proxy/:_authToken=token Resolves: trufflesecurity#1455
- Replace SaneHttpClient with DetectorHttpClientWithNoLocalAddresses to prevent SSRF attacks - Fix token cross-leakage by mapping tokens to their specific registries - Update regex to support registry URLs with port numbers - Add comprehensive tests for token-registry pairing and port numbers
The tokenRegistry struct was never instantiated or used. The code uses map[string]string from extractTokenRegistryPairs instead.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 6c19b86. Configure here.
Move extractTokenRegistryPairs call inside verify block to avoid unnecessary regex processing when verification is disabled. This optimization prevents wasted regex work across potentially millions of chunks during scanning.
MuneebUllahKhan222
left a comment
There was a problem hiding this comment.
Hi @jainlakshya ,
Thank you for your contribution. I’ve requested a couple of changes. Please note that the same changes will also need to be applied to the npmtokenv2 detector.
| // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. | ||
| keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"npm"}) + `\b([0-9Aa-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\b`) | ||
|
|
||
| npmrcPat = regexp.MustCompile(`//([^/]+(?:/[^:]+)*)/:_authToken\s*=\s*([^\s]+)`) |
There was a problem hiding this comment.
Can we update the regex to //([^/]+(?:/[^:]+)*)/:_authToken\s*=\s*[^\s]+ so that we do not capture the token from this regex.
| return | ||
| } | ||
|
|
||
| func extractTokenRegistryPairs(data string) map[string]string { |
There was a problem hiding this comment.
Replace this func with as we would only like to capture the registry from npmrcPat
func extractTokenRegistryPairs(data string) map[string]struct{} {
matches := npmrcPat.FindAllStringSubmatch(data, -1)
registryMap := make(map[string]struct{})
for _, match := range matches {
registryMap[match[1]] = struct{}{}
}
return registryMap
}
| return false, nil | ||
| } | ||
|
|
||
| func buildRegistryURL(registry string) string { |
There was a problem hiding this comment.
Can we use url package to do the url parsing here.
| } | ||
| } | ||
|
|
||
| isVerified, extraData := verifyToken(ctx, resMatch, registry) |
There was a problem hiding this comment.
Return verficationErr from verifyToken func and then set it on results struct.
You can use this for inspiration.
|
|
||
| isVerified, extraData := verifyToken(ctx, resMatch, registry) | ||
| s1.Verified = isVerified | ||
| if isVerified { |
There was a problem hiding this comment.
Add SecretParts on result struct.

Summary
Implements #1455 - Modified npm token detectors (v1 and v2) to extract and verify against custom registry URLs when found in .npmrc format, instead of always verifying against registry.npmjs.org.
Motivation
Enterprise environments often use private npm registries (Nexus, Artifactory, JFrog, etc.) instead of the public registry.npmjs.org. Previously, valid tokens for these registries were incorrectly marked as unverified because TruffleHog only checked against registry.npmjs.org.
Changes
Supported Formats
The detectors now recognize and verify tokens in .npmrc format:
//artifactory.example.com/:_authToken=3aAcac6c-9847-23d9-ce65-917590b81cf0
//nexus.example.com/repository/npm-proxy/:_authToken=npm_hK0FJXBYCkejhEMY4Kp6bOOZn1DlfBOmtbJY
Technical Details
Testing
Breaking Changes
None. This is backward compatible - tokens without registry context still verify against registry.npmjs.org as before.
Checklist
Note
Medium Risk
Changes verification network targets for
npmtoken/npmtokenv2by deriving registry hosts from scanned content, which could affect outbound request behavior and verification accuracy (mitigated by the no-local-address HTTP client).Overview
NPM token detectors (v1 and v2) now parse
.npmrc-style lines (//<registry>/:_authToken=<token>) to infer a registry host/path for each discovered token and verify against that registry’s/-/whoamiendpoint, falling back toregistry.npmjs.orgwhen no context is found.Verification logic was refactored into helpers (
extractTokenRegistryPairs,buildRegistryURL,verifyToken), switched todetectors.DetectorHttpClientWithNoLocalAddresses, and successful verifications now record theregistryinAnalysisInfo. Extensive unit tests were added for registry extraction and URL building in both detectors.Reviewed by Cursor Bugbot for commit 817e5e2. Bugbot is set up for automated code reviews on this repo. Configure here.