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

Fix agent secrets obfuscation #515

Merged
merged 1 commit into from
Nov 7, 2023
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
60 changes: 46 additions & 14 deletions core/agent/htask.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import (
"syscall"
"time"

"github.com/nqd/flat"
"github.com/NethServer/ns8-core/core/agent/models"
"github.com/NethServer/ns8-core/core/agent/validation"
"github.com/go-redis/redis/v8"
Expand Down Expand Up @@ -402,21 +401,54 @@ func publishStatus(client redis.Cmdable, progressChannel string, actionDescripto
}
}

func obscureTaskInput(payload string) string {
var jsonDyn map[string]interface{}
json.Unmarshal([]byte(payload), &jsonDyn)
flattenedInput, _ := flat.Flatten(jsonDyn, nil)
func obscureTaskInput(jsonStr string) string {
var jsonData map[string]interface{}
if err := json.Unmarshal([]byte(jsonStr), &jsonData); err != nil {
log.Println(SD_ERR+"Error unmarshalling JSON:", err)
return jsonStr
}

recursiveObscureSensitiveKeys(jsonData)

updatedJson, err := json.Marshal(jsonData)
if err != nil {
log.Println(SD_ERR+"Error marshalling JSON:", err)
return jsonStr
}

return string(updatedJson)
}

func isSensitive(target string) bool {
sensitiveList := []string{"password", "secret", "token"}
// search for sensitve data, in sensitive list
for k, _ := range flattenedInput {
for _, s := range sensitiveList {
if strings.HasPrefix(k, "data.") && strings.HasSuffix("." + strings.ToLower(k), strings.ToLower(s)) {
flattenedInput[k] = "XXX"
ltarget := strings.ToLower(target)
for _, sensitive := range sensitiveList {
if strings.HasSuffix(ltarget, sensitive) {
return true
}
}
return false
}

func recursiveObscureSensitiveKeys(data interface{}) {
switch v := data.(type) {
case map[string]interface{}:
// It's an object, so iterate through its key-value pairs
for key, value := range v {
// Recursively update the value
recursiveObscureSensitiveKeys(value)

// Check for sensitive keys
if isSensitive(key) {
v[key] = "XXX" // replace the secret value
}
}

case []interface{}:
// It's an array, so iterate through its elements
for _, item := range v {
// Recursively update the element
recursiveObscureSensitiveKeys(item)
}
}
obscuredTask, _ := flat.Unflatten(flattenedInput, nil)
// convert to JSON string
taskJson, _ := json.Marshal(obscuredTask)
return string(taskJson[:])
}
9 changes: 9 additions & 0 deletions core/agent/test/suite/10__obfuscate_input.robot
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,12 @@ Passwords are obfuscated in Redis context keys
When The command is received set obfuscate-test/context
Then The task context should contain XXX
And The task context should contain PRE-SERVED

Obfuscation does not alter the input structure
Given The task is submitted obfuscate-test {"tags":["t1","t2"],"account_info":{"password":"Nethesis,1234","claims":["c1","c2"],"ratio":1.2},"password_not_replaced":"PRE-SERVED"}
When The command is received set obfuscate-test/context
Then The task context should contain XXX
And The task context should contain PRE-SERVED
And The task context should contain ["t1","t2"]
And The task context should contain ["c1","c2"]
And The task context should contain 1.2
Loading