MCPcopy Create free account
hub / github.com/npm/cli / matchRegistry

Function matchRegistry

workspaces/arborist/lib/script-allowed.js:137–198  ·  view source on GitHub ↗
(node, parsed, failClosed)

Source from the content-addressed store, hash-verified

135}
136
137const matchRegistry = (node, parsed, failClosed) => {
138 // If this node is not a registry dep, refuse the match. A registry-style
139 // key (`pkg`, `pkg@1`, `pkg@1 || 2`) must not match a tarball or git node
140 // even if their names happen to coincide.
141 if (!isRegistryNode(node)) {
142 return false
143 }
144
145 // Derive the trusted name+version from the lockfile's resolved URL.
146 // Never use `node.packageName` / `node.version` here: those read from
147 // the tarball's own package.json and can be forged by a malicious
148 // publisher to bypass an allowScripts entry.
149 const trusted = getTrustedRegistryIdentity(node)
150 if (!trusted || trusted.name !== parsed.name) {
151 return false
152 }
153
154 // `tag` covers `pkg@latest`. Rejected up front by validatePolicy in
155 // resolve-allow-scripts.js because tags look like a pin but can't be
156 // verified at install time. Defense-in-depth: if one slips through
157 // (e.g. arborist invoked directly without the resolver), don't match.
158 if (parsed.type === 'tag') {
159 /* istanbul ignore next: validatePolicy filters this; defensive */
160 return false
161 }
162
163 // `range` includes `pkg@^1`, `pkg@1 || 2`, `pkg@*`, `pkg@>=0`, and bare
164 // names like `pkg` (npa parses these as range with fetchSpec='*'). The
165 // RFC permits bare names (name-only allow) and exact versions joined by
166 // `||`; ranges like ^/~/>=/< are rejected because they would silently
167 // allow versions the user has never reviewed.
168 if (parsed.type === 'range') {
169 // Bare name or `pkg@*`: treat as name-only allow.
170 if (parsed.fetchSpec === '*' || parsed.rawSpec === '' || parsed.rawSpec === '*') {
171 return true
172 }
173 if (!isExactVersionDisjunction(parsed.fetchSpec)) {
174 return false
175 }
176 // Unverifiable version (omit-lockfile-registry-resolved): a deny blocks,
177 // an allow is refused.
178 if (!trusted.version) {
179 return failClosed
180 }
181 return semver.satisfies(trusted.version, parsed.fetchSpec, { loose: true })
182 }
183
184 // `version` is an exact pin like `pkg@1.2.3`.
185 /* istanbul ignore else: parsed.type at this point is always 'version';
186 the istanbul-ignored fallback below handles the impossible case. */
187 if (parsed.type === 'version') {
188 // Unverifiable version: a deny blocks, an allow is refused.
189 if (!trusted.version) {
190 return failClosed
191 }
192 return trusted.version === parsed.fetchSpec
193 }
194

Callers 1

matchesFunction · 0.85

Calls 4

isRegistryNodeFunction · 0.85
satisfiesMethod · 0.80

Tested by

no test coverage detected