Harden marketplace install error handling
This commit is contained in:
parent
a9dc972ce4
commit
84bc36f071
2 changed files with 20 additions and 2 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue