Skip to content

Commit f0a99c1

Browse files
bhagya05bhagyapurbayaron2
authored
Fix metadata header value sanitization (#3581)
Signed-off-by: Bhagya Singh Purba <[email protected]> Co-authored-by: bhagyapurba <[email protected]> Co-authored-by: Yaron Schneider <[email protected]>
1 parent b969bbf commit f0a99c1

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

common/component/azure/blobstorage/request.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func SanitizeMetadata(log logger.Logger, metadata map[string]string) map[string]
107107
n = 0
108108
newVal := make([]byte, len(val))
109109
for i := range len(val) {
110-
if val[i] > 127 || val[i] == 0 {
110+
if val[i] > 127 || (isCTL(val[i]) && !isLWS(val[i])) {
111111
continue
112112
}
113113
newVal[n] = val[i]
@@ -118,3 +118,10 @@ func SanitizeMetadata(log logger.Logger, metadata map[string]string) map[string]
118118

119119
return res
120120
}
121+
122+
func isLWS(b byte) bool { return b == ' ' || b == '\t' }
123+
124+
func isCTL(b byte) bool {
125+
const del = 0x7f // a CTL
126+
return b < ' ' || b == del
127+
}

common/component/azure/blobstorage/request_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func TestSanitizeRequestMetadata(t *testing.T) {
6060
"somecustomfield": "some-custom-value",
6161
"specialfield": "special:valueÜ",
6262
"not-allowed:": "not-allowed",
63+
"ctr-characters": string([]byte{72, 20, 1, 0, 101, 120}),
6364
}
6465
meta := SanitizeMetadata(log, m)
6566
_ = assert.NotNil(t, meta["somecustomfield"]) &&
@@ -68,5 +69,52 @@ func TestSanitizeRequestMetadata(t *testing.T) {
6869
assert.Equal(t, "special:value", *meta["specialfield"])
6970
_ = assert.NotNil(t, meta["notallowed"]) &&
7071
assert.Equal(t, "not-allowed", *meta["notallowed"])
72+
_ = assert.NotNil(t, meta["ctrcharacters"]) &&
73+
assert.Equal(t, string([]byte{72, 101, 120}), *meta["ctrcharacters"])
7174
})
7275
}
76+
77+
func TestIsLWS(t *testing.T) {
78+
// Test cases for isLWS
79+
tests := []struct {
80+
input byte
81+
expected bool
82+
}{
83+
{' ', true}, // Space character, should return true
84+
{'\t', true}, // Tab character, should return true
85+
{'A', false}, // Non-LWS character, should return false
86+
{'1', false}, // Non-LWS character, should return false
87+
{'\n', false}, // Newline, a CTL but not LWS, should return false
88+
{0x7F, false}, // DEL character, a CTL but not LWS, should return false
89+
}
90+
91+
for _, tt := range tests {
92+
t.Run("Testing for LWS", func(t *testing.T) {
93+
result := isLWS(tt.input)
94+
assert.Equal(t, tt.expected, result, "input: %v", tt.input)
95+
})
96+
}
97+
}
98+
99+
func TestIsCTL(t *testing.T) {
100+
// Test cases for isCTL
101+
tests := []struct {
102+
input byte
103+
expected bool
104+
}{
105+
{0x00, true}, // NUL, a control character
106+
{0x1F, true}, // US (Unit Separator), a control character
107+
{'\n', true}, // Newline, a control character
108+
{0x7F, true}, // DEL, a control character
109+
{'A', false}, // Non-CTL character
110+
{'1', false}, // Non-CTL character
111+
{' ', false}, // Space is not a CTL (although LWS)
112+
}
113+
114+
for _, tt := range tests {
115+
t.Run("Testing for CTL characters", func(t *testing.T) {
116+
result := isCTL(tt.input)
117+
assert.Equal(t, tt.expected, result, "input: %v", tt.input)
118+
})
119+
}
120+
}

0 commit comments

Comments
 (0)