fix: widen installer regex allowlists and deduplicate safeExternalHref calls

- SAFE_GO_MODULE: allow uppercase in module paths (A-Z)
- SAFE_BREW_FORMULA: allow @ for versioned formulas (python@3.12)
- SAFE_UV_PACKAGE: allow extras [standard] and equality pins ==
- Cache safeExternalHref result in skills detail API key section
This commit is contained in:
Val Alexander
2026-03-24 01:46:33 -05:00
parent cb58e45130
commit b61a875d56
2 changed files with 9 additions and 7 deletions

View File

@@ -112,10 +112,11 @@ function buildNodeInstallCommand(packageName: string, prefs: SkillsInstallPrefer
}
// Strict allowlist patterns to prevent option injection and malicious package names.
const SAFE_BREW_FORMULA = /^[a-z0-9][a-z0-9+._-]*(\/[a-z0-9][a-z0-9+._-]*){0,2}$/;
const SAFE_BREW_FORMULA = /^[a-z0-9][a-z0-9+._@-]*(\/[a-z0-9][a-z0-9+._@-]*){0,2}$/;
const SAFE_NODE_PACKAGE = /^(@[a-z0-9._-]+\/)?[a-z0-9._-]+(@[a-z0-9^~>=<.*|-]+)?$/;
const SAFE_GO_MODULE = /^[a-zA-Z0-9][a-zA-Z0-9._/-]*@[a-z0-9v._-]+$/;
const SAFE_UV_PACKAGE = /^[a-z0-9][a-z0-9._-]*(>=?[a-z0-9._-]+)?$/i;
const SAFE_UV_PACKAGE =
/^[a-z0-9][a-z0-9._-]*(\[[a-z0-9,._-]+\])?(([><=!~]=?|===?)[a-z0-9.*_-]+)?$/i;
function assertSafeInstallerValue(value: string, kind: string, pattern: RegExp): string | null {
const trimmed = value.trim();

View File

@@ -330,13 +330,14 @@ function renderSkillDetail(skill: SkillStatusEntry, props: SkillsProps) {
props.onEdit(skill.skillKey, (e.target as HTMLInputElement).value)}
/>
</div>
${
safeExternalHref(skill.homepage)
${(() => {
const href = safeExternalHref(skill.homepage);
return href
? html`<div class="muted" style="font-size: 13px;">
Get your key: <a href="${safeExternalHref(skill.homepage)}" target="_blank" rel="noopener noreferrer">${skill.homepage}</a>
Get your key: <a href="${href}" target="_blank" rel="noopener noreferrer">${skill.homepage}</a>
</div>`
: nothing
}
: nothing;
})()}
<button
class="btn primary"
?disabled=${busy}