Repository navigation
fix: strip trailing slash from registry URL - #14
Conversation
The default registry input was `https://registry.npmjs.org/` (trailing slash) and was passed verbatim to `ut config set registry`. utoo joins URLs as `{registry}/{pkg}`, producing `//<pkg>`, which npm's registry rejects with HTTP 406 Not Acceptable — breaking dependency resolution. Drop the trailing slash from the default and normalize any caller-supplied trailing slashes in the action before use. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request updates the default npm registry URL to remove the trailing slash and adds logic to strip trailing slashes from the registry option in src/action.ts. A critical command injection vulnerability was identified in how the registry variable is used in shell execution, and it is recommended to validate the URL input and use safe execution methods.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| const registry = (options.registry || "https://registry.npmjs.org").replace( | ||
| /\/+$/, | ||
| "", | ||
| ); |
There was a problem hiding this comment.
Security Vulnerability: Command Injection
The registry variable is constructed from user input (options.registry) and later passed directly to execSync with shell: true in setRegistry (line 207):
execSync(`ut config set registry ${registry} --global`, { ... })Because shell: true is used, this creates a Command Injection vulnerability if a malicious or malformed registry URL is provided (e.g., containing shell metacharacters like ;, &, or |).
Recommendations:
- Input Validation (Defense-in-Depth): Validate that the registry is a valid URL before using it. This can be done by parsing it with
new URL()which will throw an error for invalid URLs. - Safe Execution (Primary Fix): Refactor
setRegistryto use@actions/exec'sgetExecOutput(which is already imported) instead ofchild_process.execSyncwithshell: true. This avoids spawning a shell and safely passes arguments as an array.
For example, refactor setRegistry as follows:
async function setRegistry(registry: string): Promise<void> {
try {
await getExecOutput("ut", ["config", "set", "registry", registry, "--global"]);
} catch (error) {
warning(`Failed to set npm registry: ${error}`);
}
}| const registry = (options.registry || "https://registry.npmjs.org").replace( | |
| /\/+$/, | |
| "", | |
| ); | |
| const registryInput = options.registry || "https://registry.npmjs.org"; | |
| try { | |
| new URL(registryInput); | |
| } catch { | |
| throw new Error(`Invalid registry URL: ${registryInput}`); | |
| } | |
| const registry = registryInput.replace(/\/+$/, ""); |
Problem
The default
registryinput ishttps://registry.npmjs.org/(trailing slash). The action passes it verbatim tout config set registry, so utoo's global config stores the trailing slash. utoo builds metadata URLs as{registry}/{pkg}, which then yields a double slash:npm's registry returns HTTP 406 Not Acceptable for the
//<pkg>path, so dependency resolution fails. Seen in ant-design CI:Fix
action.yml,src/index.ts).src/action.tsbefore it's used (config write, install, manifest fetch), so a user-provided.../can't reintroduce the bug.dist/setup/index.js.🤖 Generated with Claude Code