Read secret environment variables once per command, then unset them (closes #60)
check / check (push) Failing after 1s
check / check (push) Failing after 1s
init and vault create put the mnemonic into the process environment for vault.CreateVault to read back, so every program they ran, gpg included, inherited it, and SB_SECRET_MNEMONIC and SB_UNLOCK_PASSPHRASE were read at 13 places and never unset. Each command that may need them now reads both once, in its RunE, into locked buffers on the CLI Instance, and unsets them at once. The buffers are passed down: vault.CreateVault takes the mnemonic, a Vault carries Mnemonic and UnlockPassphrase, and the PGP, keychain and Secure Enclave unlocker constructors take both; CreatePGPUnlocker sets them on the vault it loads through SetMnemonic and SetUnlockPassphrase, new in VaultInterface. README warns against both variables. Model: opus-5-5
This commit was merged in pull request #94.
This commit is contained in:
@@ -3,7 +3,6 @@ package vault_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.eeqj.de/sneak/secret/internal/secret"
|
||||
"git.eeqj.de/sneak/secret/internal/vault"
|
||||
"github.com/awnumar/memguard"
|
||||
"github.com/spf13/afero"
|
||||
@@ -13,15 +12,13 @@ import (
|
||||
// TestGetSecretVersionRejectsPathTraversal verifies that GetSecretVersion
|
||||
// validates the secret name and rejects path traversal attempts.
|
||||
// This is a regression test for https://git.eeqj.de/sneak/secret/issues/13
|
||||
//
|
||||
//nolint:paralleltest // t.Setenv in parent forbids parallel subtests
|
||||
func TestGetSecretVersionRejectsPathTraversal(t *testing.T) {
|
||||
t.Setenv(secret.EnvMnemonic, testMnemonic)
|
||||
t.Setenv(secret.EnvUnlockPassphrase, testPassphrase)
|
||||
t.Parallel()
|
||||
|
||||
fs := afero.NewMemMapFs()
|
||||
|
||||
vlt, err := vault.CreateVault(fs, testStateDir, testVaultName)
|
||||
vlt, err := vault.CreateVault(fs, testStateDir, testVaultName,
|
||||
testMnemonicBuffer(t))
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add a legitimate secret so the vault is set up
|
||||
@@ -41,6 +38,8 @@ func TestGetSecretVersionRejectsPathTraversal(t *testing.T) {
|
||||
|
||||
for _, name := range maliciousNames {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := vlt.GetSecretVersion(name, "")
|
||||
require.Error(t, err,
|
||||
"GetSecretVersion should reject malicious name: %s", name)
|
||||
@@ -53,12 +52,12 @@ func TestGetSecretVersionRejectsPathTraversal(t *testing.T) {
|
||||
// TestGetSecretRejectsPathTraversal verifies GetSecret (which calls
|
||||
// GetSecretVersion) also rejects path traversal names.
|
||||
func TestGetSecretRejectsPathTraversal(t *testing.T) {
|
||||
t.Setenv(secret.EnvMnemonic, testMnemonic)
|
||||
t.Setenv(secret.EnvUnlockPassphrase, testPassphrase)
|
||||
t.Parallel()
|
||||
|
||||
fs := afero.NewMemMapFs()
|
||||
|
||||
vlt, err := vault.CreateVault(fs, testStateDir, testVaultName)
|
||||
vlt, err := vault.CreateVault(fs, testStateDir, testVaultName,
|
||||
testMnemonicBuffer(t))
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = vlt.GetSecret("../../../etc/passwd")
|
||||
@@ -68,15 +67,13 @@ func TestGetSecretRejectsPathTraversal(t *testing.T) {
|
||||
|
||||
// TestGetSecretObjectRejectsPathTraversal verifies GetSecretObject
|
||||
// also validates names and rejects path traversal attempts.
|
||||
//
|
||||
//nolint:paralleltest // t.Setenv in parent forbids parallel subtests
|
||||
func TestGetSecretObjectRejectsPathTraversal(t *testing.T) {
|
||||
t.Setenv(secret.EnvMnemonic, testMnemonic)
|
||||
t.Setenv(secret.EnvUnlockPassphrase, testPassphrase)
|
||||
t.Parallel()
|
||||
|
||||
fs := afero.NewMemMapFs()
|
||||
|
||||
vlt, err := vault.CreateVault(fs, testStateDir, testVaultName)
|
||||
vlt, err := vault.CreateVault(fs, testStateDir, testVaultName,
|
||||
testMnemonicBuffer(t))
|
||||
require.NoError(t, err)
|
||||
|
||||
maliciousNames := []string{
|
||||
@@ -87,6 +84,8 @@ func TestGetSecretObjectRejectsPathTraversal(t *testing.T) {
|
||||
|
||||
for _, name := range maliciousNames {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := vlt.GetSecretObject(name)
|
||||
require.Error(t, err, "GetSecretObject should reject: %s", name)
|
||||
require.Contains(t, err.Error(), "invalid secret name")
|
||||
|
||||
Reference in New Issue
Block a user