Skip to content

Commit

Permalink
fix: disable_cypher_qc and other 3+ segment JSON keys (#190)
Browse files Browse the repository at this point in the history
* fix: disable_cypher_qc and other 3+ segment JSON keys

The previous env var fixes introduced a bug when attempting to find the
end of a key when the key contains multiple underscores

Regression tests have been added to avoid further issues

* chore: drop superfluous var
  • Loading branch information
superlinkx authored Nov 9, 2023
1 parent 9da40b1 commit 69df0e6
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
5 changes: 4 additions & 1 deletion cmd/api/src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package config
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -240,7 +241,9 @@ func SetValuesFromEnv(varPrefix string, target any, env []string) error {
if formattedPrefix := formatEnvironmentVariablePrefix(varPrefix); strings.HasPrefix(key, formattedPrefix) {
cfgKeyPath := strings.TrimPrefix(key, formattedPrefix)

if err := SetValue(target, cfgKeyPath, valueStr); err != nil {
if err := SetValue(target, cfgKeyPath, valueStr); errors.Is(err, InvalidConfigurationPathError) {
log.Warnf("%s", err)
} else if err != nil {
return err
}
}
Expand Down
11 changes: 6 additions & 5 deletions cmd/api/src/config/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@
package config

import (
"errors"
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
"time"

"github.com/specterops/bloodhound/log"
"github.com/specterops/bloodhound/src/serde"
)

var structTagRegex = regexp.MustCompile(`(\w+):"([^"]+)"`)
var InvalidConfigurationPathError = errors.New("Unable to find a configuration element by path")

// taggedField represents a struct field by its index and a parsed representation of any tags associated with the
// struct field.
Expand Down Expand Up @@ -270,10 +271,11 @@ func SetValue(target any, path, value string) error {
break
}

lookahead := idx + 1
lookahead := idx

for lookahead < len(pathParts) {
remainingFullPath := strings.Join(append([]string{nextPathPart}, pathParts[lookahead]), "_")
// Make sure to add one to lookahead, as we want to get the range starting at base and going 1 or more indexes beyond it
remainingFullPath := strings.Join(pathParts[idx:lookahead+1], "_")

if taggedFieldName == remainingFullPath {
cursor = cursor.Field(taggedField.Field)
Expand All @@ -291,8 +293,7 @@ func SetValue(target any, path, value string) error {
}

if !found {
log.Warnf("Unable to find a configuration element by path: %s", path)
return nil
return fmt.Errorf("%w: %s", InvalidConfigurationPathError, path)
}
}

Expand Down
11 changes: 9 additions & 2 deletions cmd/api/src/config/reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/specterops/bloodhound/src/config"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestSetValue(t *testing.T) {
Expand All @@ -41,8 +42,14 @@ func TestSetValue(t *testing.T) {
assert.Equal(t, uint32(10), cfg.Crypto.Argon2.MemoryKibibytes)
})

t.Run("attempting to set a value to an unknown field should not fail", func(t *testing.T) {
assert.Nil(t, config.SetValue(&cfg, "crypto_fake", "string"))
t.Run("key with two underscores", func(t *testing.T) {
require.Nil(t, config.SetValue(&cfg, "disable_cypher_qc", "true"))
assert.Equal(t, true, cfg.DisableCypherQC)
})

t.Run("key with three underscores", func(t *testing.T) {
require.Nil(t, config.SetValue(&cfg, "max_graphdb_cache_size", "0"))
assert.Equal(t, 0, cfg.MaxGraphQueryCacheSize)
})

t.Run("edge cases", func(t *testing.T) {
Expand Down

0 comments on commit 69df0e6

Please sign in to comment.