Harden marketplace install error handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

This commit is contained in:
Snider 2026-04-15 21:53:52 +01:00
parent a9dc972ce4
commit 84bc36f071
2 changed files with 20 additions and 2 deletions

View file

@ -14,6 +14,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"unicode"
@ -44,6 +45,8 @@ type Installer struct {
const maxManifestBytes = 1 << 20
var credentialRedactionPattern = regexp.MustCompile(`(?i)\b([a-z][a-z0-9+.-]*://)([^@\s/]+)@`)
func (i Installer) FetchManifest(ctx context.Context, manifestURL string) (Manifest, error) {
client := i.HTTPClient
if client == nil {
@ -164,7 +167,7 @@ func (i Installer) Install(ctx context.Context, manifest Manifest) (string, erro
}
cmd := exec.CommandContext(ctx, binary, args...)
if output, err := cmd.CombinedOutput(); err != nil {
return "", fmt.Errorf("git clone failed: %w: %s", err, strings.TrimSpace(string(output)))
return "", fmt.Errorf("git clone failed: %w: %s", err, sanitizeCommandOutput(output))
}
if err := writeInstalledManifest(targetDir, manifest); err != nil {
return "", err
@ -304,3 +307,16 @@ func writeInstalledManifest(targetDir string, manifest Manifest) error {
}
return os.WriteFile(filepath.Join(manifestDir, "marketplace.yaml"), data, 0o644)
}
func sanitizeCommandOutput(output []byte) string {
trimmed := strings.TrimSpace(string(output))
if trimmed == "" {
return "command produced no output"
}
sanitized := credentialRedactionPattern.ReplaceAllString(trimmed, "$1[redacted]@")
const maxOutputChars = 512
if len(sanitized) > maxOutputChars {
sanitized = sanitized[:maxOutputChars] + "..."
}
return sanitized
}

View file

@ -245,7 +245,7 @@ func TestMarketplace_Install_RejectsDashPrefixedRef(t *testing.T) {
func TestMarketplace_Install_Ugly(t *testing.T) {
scriptDir := t.TempDir()
scriptPath := filepath.Join(scriptDir, "git")
require.NoError(t, os.WriteFile(scriptPath, []byte("#!/bin/sh\nexit 1\n"), 0o755))
require.NoError(t, os.WriteFile(scriptPath, []byte("#!/bin/sh\nprintf '%s\\n' 'fatal: https://token:secret@example.com/repo.git' >&2\nexit 1\n"), 0o755))
installer := Installer{
GitBinary: scriptPath,
@ -258,6 +258,8 @@ func TestMarketplace_Install_Ugly(t *testing.T) {
}))
require.Error(t, err)
assert.Contains(t, err.Error(), "git clone failed")
assert.NotContains(t, err.Error(), "secret")
assert.NotContains(t, err.Error(), "token:")
}
func TestMarketplace_Verify_Good(t *testing.T) {