Reject invalid secret names before any command builds a path (closes #33)
check / check (push) Successful in 49s
check / check (push) Successful in 49s
`secret rm ..` resolved to the vault directory and deleted the whole vault; `secret rm .` and `secret rm ""` deleted every secret. rm, mv, the version commands, encrypt and decrypt built paths from the name without checking it; import checked it only after reading the source file. vault.ValidateSecretName wraps the existing name rule and its error states the rule. Each of those commands calls it on the name as given, before building any path; a move checks both names before switching the current vault. AddSecret, GetSecretVersion and GetSecretObject use it too. The regression test copies two in-memory vaults for each rejected command and requires the exact error and an unchanged state directory. Model: opus-5-5
This commit is contained in:
+35
-2
@@ -603,6 +603,11 @@ func printSecretsTable(
|
||||
func (cli *Instance) ImportSecret(
|
||||
cmd *cobra.Command, secretName, sourceFile string, force bool,
|
||||
) error {
|
||||
err := vault.ValidateSecretName(secretName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get current vault
|
||||
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
|
||||
if err != nil {
|
||||
@@ -649,6 +654,11 @@ func (cli *Instance) ImportSecret(
|
||||
|
||||
// RemoveSecret removes a secret from the vault
|
||||
func (cli *Instance) RemoveSecret(cmd *cobra.Command, secretName string, _ bool) error {
|
||||
err := vault.ValidateSecretName(secretName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get current vault
|
||||
currentVlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
|
||||
if err != nil {
|
||||
@@ -737,10 +747,22 @@ func (cli *Instance) MoveSecret(
|
||||
destSecretName = srcSecretName
|
||||
}
|
||||
|
||||
// Check both names before selecting a vault below, so that a rejected
|
||||
// move leaves the current vault as it was.
|
||||
err := vault.ValidateSecretName(srcSecretName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = vault.ValidateSecretName(destSecretName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Same vault? Use simple rename if possible (optimization)
|
||||
if srcVaultName == destVaultName {
|
||||
// Select the vault and do a simple move
|
||||
err := vault.SelectVault(cli.fs, cli.stateDir, srcVaultName)
|
||||
err = vault.SelectVault(cli.fs, cli.stateDir, srcVaultName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to select vault '%s': %w", srcVaultName, err)
|
||||
}
|
||||
@@ -757,6 +779,16 @@ func (cli *Instance) MoveSecret(
|
||||
func (cli *Instance) moveSecretWithinVault(
|
||||
cmd *cobra.Command, source, dest string, force bool,
|
||||
) error {
|
||||
err := vault.ValidateSecretName(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = vault.ValidateSecretName(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
currentVlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -808,7 +840,8 @@ func (cli *Instance) moveSecretWithinVault(
|
||||
return nil
|
||||
}
|
||||
|
||||
// moveSecretCrossVault handles moving between different vaults
|
||||
// moveSecretCrossVault handles moving between different vaults. Its caller,
|
||||
// MoveSecret, has already checked both secret names.
|
||||
func (cli *Instance) moveSecretCrossVault(
|
||||
cmd *cobra.Command,
|
||||
srcVaultName, srcSecretName,
|
||||
|
||||
Reference in New Issue
Block a user