Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## v?.??.? (Unreleased)

BUG FIXES

- Fixed `encode_path` incorrectly encoding hyphens (`-`), which caused 403 errors on Vault 1.15+ [GH-350, GH-343]
- Fixed `FrozenError` when loading the gem with OpenSSL 4.0.0+ by removing modification of `OpenSSL::SSL::SSLContext::DEFAULT_PARAMS`. Modern Ruby (3.1+) already has secure SSL defaults. [GH-366, GH-381]

## v0.19.0 (December 3, 2025)

BREAKING CHANGES
Expand Down
2 changes: 1 addition & 1 deletion lib/vault/encode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module EncodePath
#
# @return [String]
def encode_path(path)
path.b.gsub(%r!([^a-zA-Z0-9_.-/]+)!) { |m|
path.b.gsub(%r!([^a-zA-Z0-9_.\-/]+)!) { |m|
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
}
end
Expand Down
67 changes: 67 additions & 0 deletions spec/unit/encode_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

require "spec_helper"

module Vault
describe EncodePath do
describe "#encode_path" do
it "does not encode alphanumeric characters" do
expect(EncodePath.encode_path("abcXYZ123")).to eq("abcXYZ123")
end

it "does not encode hyphens" do
expect(EncodePath.encode_path("lookup-self")).to eq("lookup-self")
expect(EncodePath.encode_path("auth/token/lookup-self")).to eq("auth/token/lookup-self")
end

it "does not encode underscores" do
expect(EncodePath.encode_path("my_secret")).to eq("my_secret")
end

it "does not encode periods" do
expect(EncodePath.encode_path("file.txt")).to eq("file.txt")
end

it "does not encode forward slashes" do
expect(EncodePath.encode_path("a/b/c")).to eq("a/b/c")
end

it "encodes spaces as %20" do
expect(EncodePath.encode_path("my secret")).to eq("my%20secret")
end

it "encodes special characters" do
expect(EncodePath.encode_path("test@example")).to eq("test%40example")
expect(EncodePath.encode_path("key=value")).to eq("key%3Dvalue")
expect(EncodePath.encode_path("a&b")).to eq("a%26b")
end

it "encodes colons" do
expect(EncodePath.encode_path("foo:bar")).to eq("foo%3Abar")
end

it "encodes tildes" do
expect(EncodePath.encode_path("test~value")).to eq("test%7Evalue")
end

it "encodes unicode characters" do
expect(EncodePath.encode_path("caf\u00e9")).to eq("caf%C3%A9")
end

it "handles empty strings" do
expect(EncodePath.encode_path("")).to eq("")
end

it "handles paths with multiple encoded segments" do
expect(EncodePath.encode_path("secret/my secret/sub path")).to eq("secret/my%20secret/sub%20path")
end

it "handles Vault auth paths correctly" do
expect(EncodePath.encode_path("auth/token/lookup-self")).to eq("auth/token/lookup-self")
expect(EncodePath.encode_path("auth/token/renew-self")).to eq("auth/token/renew-self")
expect(EncodePath.encode_path("sys/mounts/secret-store")).to eq("sys/mounts/secret-store")
end
end
end
end