Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace sha1 with sha2-256 #19779

Merged
merged 9 commits into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from 7 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
16 changes: 16 additions & 0 deletions .chloggen/introduce_sha2Hasher.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: attributesprocessor, resourceprocessor

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add feature gate to support using SHA2-256 instead of SHA-1 for hashing

# One or more tracking issues related to the change
issues: [4759, 5576]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: enable switching to use SHA-2 256 with the feature gate `coreinternal.attraction.hash.sha256`
21 changes: 17 additions & 4 deletions internal/coreinternal/attraction/attraction.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,17 @@ import (
"strings"

"go.opentelemetry.io/collector/client"
"go.opentelemetry.io/collector/featuregate"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.uber.org/zap"
)

var enableSha256Gate = featuregate.GlobalRegistry().MustRegister(
"coreinternal.attraction.hash.sha256",
featuregate.StageAlpha,
featuregate.WithRegisterDescription("When enabled, switches hashing algorithm from SHA-1 to SHA-2 256"),
)

// Settings specifies the processor settings.
type Settings struct {
// Actions specifies the list of attributes to act on.
Expand Down Expand Up @@ -85,7 +92,9 @@ type ActionKeyValue struct {
// DELETE - Deletes the attribute. If the key doesn't exist,
// no action is performed.
// HASH - Calculates the SHA-1 hash of an existing value and overwrites the
// value with it's SHA-1 hash result.
// value with its SHA-1 hash result. If the feature gate
// `coreinternal.attraction.hash.sha256` is enabled, it uses SHA2-256
// instead.
// EXTRACT - Extracts values using a regular expression rule from the input
// 'key' to target keys specified in the 'rule'. If a target key
// already exists, it will be overridden.
Expand Down Expand Up @@ -132,8 +141,8 @@ const (
// Supports pattern which is matched against attribute key.
DELETE Action = "delete"

// HASH calculates the SHA-1 hash of an existing value and overwrites the
// value with it's SHA-1 hash result.
// HASH calculates the SHA-256 hash of an existing value and overwrites the
// value with it's SHA-256 hash result.
// Supports pattern which is matched against attribute key.
HASH Action = "hash"

Expand Down Expand Up @@ -405,7 +414,11 @@ func getSourceAttributeValue(ctx context.Context, action attributeAction, attrs

func hashAttribute(key string, attrs pcommon.Map) {
if value, exists := attrs.Get(key); exists {
sha1Hasher(value)
if enableSha256Gate.IsEnabled() {
sha2Hasher(value)
} else {
sha1Hasher(value)
}
}
}

Expand Down
30 changes: 22 additions & 8 deletions internal/coreinternal/attraction/attraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ package attraction

import (
"context"
"crypto/sha1" // #nosec
"crypto/sha1"
"crypto/sha256"
"encoding/binary"
"errors"
"fmt"
Expand Down Expand Up @@ -630,7 +631,7 @@ func TestAttributes_HashValue(t *testing.T) {
"updateme": "foo",
},
expectedAttributes: map[string]interface{}{
"updateme": sha1Hash([]byte("foo")),
"updateme": hash([]byte("foo")),
},
},
// Ensure int data types are hashed correctly
Expand All @@ -640,7 +641,7 @@ func TestAttributes_HashValue(t *testing.T) {
"updateme": intVal,
},
expectedAttributes: map[string]interface{}{
"updateme": sha1Hash(intBytes),
"updateme": hash(intBytes),
},
},
// Ensure double data types are hashed correctly
Expand All @@ -650,7 +651,7 @@ func TestAttributes_HashValue(t *testing.T) {
"updateme": doubleVal,
},
expectedAttributes: map[string]interface{}{
"updateme": sha1Hash(doubleBytes),
"updateme": hash(doubleBytes),
},
},
// Ensure bool data types are hashed correctly
Expand All @@ -660,7 +661,7 @@ func TestAttributes_HashValue(t *testing.T) {
"updateme": true,
},
expectedAttributes: map[string]interface{}{
"updateme": sha1Hash([]byte{1}),
"updateme": hash([]byte{1}),
},
},
// Ensure bool data types are hashed correctly
Expand All @@ -670,7 +671,7 @@ func TestAttributes_HashValue(t *testing.T) {
"updateme": false,
},
expectedAttributes: map[string]interface{}{
"updateme": sha1Hash([]byte{0}),
"updateme": hash([]byte{0}),
},
},
// Ensure regex pattern is being used
Expand All @@ -681,7 +682,7 @@ func TestAttributes_HashValue(t *testing.T) {
"donotupdatemebyregexp": false,
},
expectedAttributes: map[string]interface{}{
"updatemebyregexp": sha1Hash([]byte{0}),
"updatemebyregexp": hash([]byte{0}),
"donotupdatemebyregexp": false,
},
},
Expand Down Expand Up @@ -939,13 +940,26 @@ func TestValidConfiguration(t *testing.T) {

}

func hash(b []byte) string {
if enableSha256Gate.IsEnabled() {
return sha2Hash(b)
} else {
return sha1Hash(b)
}
}

func sha1Hash(b []byte) string {
// #nosec
h := sha1.New()
h.Write(b)
return fmt.Sprintf("%x", h.Sum(nil))
}

func sha2Hash(b []byte) string {
h := sha256.New()
h.Write(b)
return fmt.Sprintf("%x", h.Sum(nil))
}

type mockInfoAuth map[string]interface{}

func (a mockInfoAuth) GetAttribute(name string) interface{} {
Expand Down
40 changes: 39 additions & 1 deletion internal/coreinternal/attraction/hasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
package attraction // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/attraction"

import (
"crypto/sha1" // #nosec
"crypto/sha1"
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"math"
Expand All @@ -33,6 +34,7 @@ var (
byteFalse = [1]byte{0}
)

// Deprecated: [v0.75.0] use sha2Hasher instead.
// sha1Hasher hashes an AttributeValue using SHA1 and returns a
// hashed version of the attribute. In practice, this would mostly be used
// for string attributes but we support all types for completeness/correctness
Expand Down Expand Up @@ -69,3 +71,39 @@ func sha1Hasher(attr pcommon.Value) {

attr.SetStr(hashed)
}

// sha2Hasher hashes an AttributeValue using SHA2-256 and returns a
// hashed version of the attribute. In practice, this would mostly be used
// for string attributes but we support all types for completeness/correctness
// and eliminate any surprises.
func sha2Hasher(attr pcommon.Value) {
var val []byte
switch attr.Type() {
case pcommon.ValueTypeStr:
val = []byte(attr.Str())
case pcommon.ValueTypeBool:
if attr.Bool() {
val = byteTrue[:]
} else {
val = byteFalse[:]
}
case pcommon.ValueTypeInt:
val = make([]byte, int64ByteSize)
binary.LittleEndian.PutUint64(val, uint64(attr.Int()))
case pcommon.ValueTypeDouble:
val = make([]byte, float64ByteSize)
binary.LittleEndian.PutUint64(val, math.Float64bits(attr.Double()))
}

var hashed string
if len(val) > 0 {
h := sha256.New()
_, _ = h.Write(val)
val = h.Sum(nil)
hashedBytes := make([]byte, hex.EncodedLen(len(val)))
hex.Encode(hashedBytes, val)
hashed = string(hashedBytes)
}

attr.SetStr(hashed)
}
1 change: 1 addition & 0 deletions internal/coreinternal/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.19
require (
github.com/stretchr/testify v1.8.2
go.opentelemetry.io/collector v0.74.0
go.opentelemetry.io/collector/featuregate v0.74.0
go.opentelemetry.io/collector/pdata v1.0.0-rc8
go.opentelemetry.io/collector/semconv v0.74.0
go.uber.org/zap v1.24.0
Expand Down
2 changes: 2 additions & 0 deletions internal/coreinternal/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.