diff --git a/vault/barrier_view.go b/vault/barrier_view.go index 18ebb70118..4ad5fe69bc 100644 --- a/vault/barrier_view.go +++ b/vault/barrier_view.go @@ -28,13 +28,27 @@ func NewBarrierView(barrier SecurityBarrier, prefix string) *BarrierView { } } +// sanityCheck is used to perform a sanity check on a key +func (v *BarrierView) sanityCheck(key string) error { + if strings.Contains(key, "..") { + return fmt.Errorf("key cannot be relative path") + } + return nil +} + // logical.Storage impl. func (v *BarrierView) List(prefix string) ([]string, error) { + if err := v.sanityCheck(prefix); err != nil { + return nil, err + } return v.barrier.List(v.expandKey(prefix)) } // logical.Storage impl. func (v *BarrierView) Get(key string) (*logical.StorageEntry, error) { + if err := v.sanityCheck(key); err != nil { + return nil, err + } entry, err := v.barrier.Get(v.expandKey(key)) if err != nil { return nil, err @@ -54,6 +68,9 @@ func (v *BarrierView) Get(key string) (*logical.StorageEntry, error) { // logical.Storage impl. func (v *BarrierView) Put(entry *logical.StorageEntry) error { + if err := v.sanityCheck(entry.Key); err != nil { + return err + } nested := &Entry{ Key: v.expandKey(entry.Key), Value: entry.Value, @@ -63,6 +80,9 @@ func (v *BarrierView) Put(entry *logical.StorageEntry) error { // logical.Storage impl. func (v *BarrierView) Delete(key string) error { + if err := v.sanityCheck(key); err != nil { + return err + } return v.barrier.Delete(v.expandKey(key)) } diff --git a/vault/barrier_view_test.go b/vault/barrier_view_test.go index f3ec596dbf..235d2755c0 100644 --- a/vault/barrier_view_test.go +++ b/vault/barrier_view_test.go @@ -18,6 +18,35 @@ func TestBarrierView_spec(t *testing.T) { logical.TestStorage(t, view) } +func TestBarrierView_BadKeysKeys(t *testing.T) { + _, barrier, _ := mockBarrier(t) + view := NewBarrierView(barrier, "foo/") + + _, err := view.List("../") + if err == nil { + t.Fatalf("expected error") + } + + _, err = view.Get("../") + if err == nil { + t.Fatalf("expected error") + } + + err = view.Delete("../foo") + if err == nil { + t.Fatalf("expected error") + } + + le := &logical.StorageEntry{ + Key: "../foo", + Value: []byte("test"), + } + err = view.Put(le) + if err == nil { + t.Fatalf("expected error") + } +} + func TestBarrierView(t *testing.T) { _, barrier, _ := mockBarrier(t) view := NewBarrierView(barrier, "foo/")