Skip to content

Commit

Permalink
Allow only valid trace ID characters when decoding (#854)
Browse files Browse the repository at this point in the history
Without this change, invalid characters received from the user input causes a
bad error message to the user.  Here we check that all of the characters that
are to be decoded are valid hex characters and improve the error to the user in
the event the trace ID submitted has invalid characters.
  • Loading branch information
zalegrala committed Aug 5, 2021
1 parent 64fd2bf commit 5b24e3d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## main / unreleased

* [BUGFIX] Allow only valid trace ID characters when decoding [#854](https://github.com/grafana/tempo/pull/854) (@zalegrala)
* [CHANGE] Upgrade Cortex from v1.9.0 to v1.9.0-131-ga4bf10354 [#841](https://github.com/grafana/tempo/pull/841) (@aknuds1)
* [CHANGE] Change default tempo port from 3100 to 3200 [#770](https://github.com/grafana/tempo/pull/809) (@MurzNN)
* [ENHANCEMENT] Added hedged request metric `tempodb_backend_hedged_roundtrips_total` and a new storage agnostic `tempodb_backend_request_duration_seconds` metric that
Expand Down
15 changes: 14 additions & 1 deletion pkg/util/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"strings"

"github.com/gorilla/mux"
)
Expand Down Expand Up @@ -32,6 +33,18 @@ func ParseTraceID(r *http.Request) ([]byte, error) {
}

func hexStringToTraceID(id string) ([]byte, error) {
// The encoding/hex package does not handle non-hex characters.
// Ensure the ID has only the proper characters
for pos, idChar := range strings.Split(id, "") {
if (idChar >= "a" && idChar <= "f") ||
(idChar >= "A" && idChar <= "F") ||
(idChar >= "0" && idChar <= "9") {
continue
} else {
return nil, fmt.Errorf("trace IDs can only contain hex characters: invalid character '%s' at position %d", idChar, pos+1)
}
}

// the encoding/hex package does not like odd length strings.
// just append a bit here
if len(id)%2 == 1 {
Expand All @@ -45,7 +58,7 @@ func hexStringToTraceID(id string) ([]byte, error) {

size := len(byteID)
if size > 16 {
return nil, errors.New("trace ids can't be larger than 128 bits")
return nil, errors.New("trace IDs can't be larger than 128 bits")
}
if size < 16 {
byteID = append(make([]byte, 16-size), byteID...)
Expand Down
14 changes: 10 additions & 4 deletions pkg/util/http_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package util

import (
"errors"
"testing"

"github.com/grafana/tempo/cmd/tempo-query/tempo"
Expand All @@ -13,7 +14,7 @@ func TestHexStringToTraceID(t *testing.T) {
tc := []struct {
id string
expected []byte
expectError bool
expectError error
}{
{
id: "12",
Expand All @@ -30,20 +31,25 @@ func TestHexStringToTraceID(t *testing.T) {
{
id: "121234567890abcdef1234567890abcdef", // value too long
expected: []byte{0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef},
expectError: true,
expectError: errors.New("trace IDs can't be larger than 128 bits"),
},
{
id: "234567890abcdef", // odd length
expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef},
},
{
id: "1234567890abcdef ", // trailing space
expected: nil,
expectError: errors.New("trace IDs can only contain hex characters: invalid character ' ' at position 17"),
},
}

for _, tt := range tc {
t.Run(tt.id, func(t *testing.T) {
actual, err := hexStringToTraceID(tt.id)

if tt.expectError {
assert.Error(t, err)
if tt.expectError != nil {
assert.Equal(t, tt.expectError, err)
assert.Nil(t, actual)
return
}
Expand Down

0 comments on commit 5b24e3d

Please sign in to comment.