Skip to content

Commit

Permalink
chore: New environment variable obfuscation functionality
Browse files Browse the repository at this point in the history
Signed-off-by: Matthias Glastra <[email protected]>
  • Loading branch information
matglas committed Sep 20, 2024
1 parent b93a379 commit 9659a8c
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 2 deletions.
18 changes: 16 additions & 2 deletions attestation/environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ type Attestor struct {
Username string `json:"username"`
Variables map[string]string `json:"variables,omitempty"`

blockList map[string]struct{}
blockList map[string]struct{}
obfuscateList map[string]struct{}
}

type Option func(*Attestor)
Expand All @@ -69,9 +70,18 @@ func WithBlockList(blockList map[string]struct{}) Option {
}
}

func WithObfuscateList(obfuscateList map[string]struct{}) Option {
return func(a *Attestor) {
for key, value := range obfuscateList {
a.obfuscateList[key] = value
}
}
}

func New(opts ...Option) *Attestor {
attestor := &Attestor{
blockList: DefaultBlockList(),
blockList: DefaultBlockList(),
obfuscateList: DefaultObfuscateList(),
}

for _, opt := range opts {
Expand Down Expand Up @@ -113,6 +123,10 @@ func (a *Attestor) Attest(ctx *attestation.AttestationContext) error {
a.Variables[key] = val
})

ObfuscateEnvironmentArray(a.Variables, a.obfuscateList, func(key, val, _ string) {
a.Variables[key] = val
})

return nil
}

Expand Down
32 changes: 32 additions & 0 deletions attestation/environment/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,35 @@ func TestEnvironment(t *testing.T) {
}
}
}

func TestEnvironmentObfuscate(t *testing.T) {
attestor := New()
ctx, err := attestation.NewContext("test", []attestation.Attestor{attestor})
require.NoError(t, err)

obfuscateEnvs := map[string]struct{}{"API_TOKEN": {}, "SECRET_TEXT": {}}
secretVarValue := "secret var"
publicVarValue := "public var"
for k, _ := range obfuscateEnvs {
t.Setenv(k, secretVarValue)
}

notObfuscateEnvs := map[string]struct{}{"VAR_FOO": {}, "VAR_BAR": {}}
for k, _ := range notObfuscateEnvs {
t.Setenv(k, publicVarValue)
}

origVars := os.Environ()
require.NoError(t, attestor.Attest(ctx))
for _, env := range origVars {
origKey, _ := splitVariable(env)
if _, inObfuscateList := obfuscateEnvs[origKey]; inObfuscateList {
require.NotEqual(t, attestor.Variables[origKey], secretVarValue)
require.Equal(t, attestor.Variables[origKey], "******")
}

if _, inNotObfuscateList := notObfuscateEnvs[origKey]; inNotObfuscateList {
require.Equal(t, attestor.Variables[origKey], publicVarValue)
}
}
}
66 changes: 66 additions & 0 deletions attestation/environment/obfuscate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2021 The Witness Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package environment

import (
"fmt"
"strings"

"github.com/gobwas/glob"
)

// sourced from https://github.com/Puliczek/awesome-list-of-secrets-in-environment-variables/blob/main/raw_list.txt
func DefaultObfuscateList() map[string]struct{} {
return map[string]struct{}{
"*_TOKEN": {},
"SECRET_*": {},
"*_API_KEY": {},
"*_PASSWORD": {},
"*_JWT": {},
}
}

// FilterEnvironmentArray expects an array of strings representing environment variables. Each element of the array is expected to be in the format of "KEY=VALUE".
// blockList is the list of elements to filter from variables, and for each element of variables that does not appear in the blockList onAllowed will be called.
func ObfuscateEnvironmentArray(variables map[string]string, obfuscateList map[string]struct{}, onAllowed func(key, val, orig string)) {
obfuscateGlobList := []glob.Glob{}

for k, _ := range obfuscateList {
if strings.Contains(k, "*") {
obfuscateGlobCompiled, err := glob.Compile(k)
if err != nil {
fmt.Errorf("obfuscate glob pattern could not be interpreted: %w", err)

Check failure on line 44 in attestation/environment/obfuscate.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `fmt.Errorf` is not checked (errcheck)

Check failure on line 44 in attestation/environment/obfuscate.go

View workflow job for this annotation

GitHub Actions / lint

unusedresult: result of fmt.Errorf call not used (govet)

Check failure on line 44 in attestation/environment/obfuscate.go

View workflow job for this annotation

GitHub Actions / lint

SA4017: Errorf doesn't have side effects and its return value is ignored (staticcheck)

Check failure on line 44 in attestation/environment/obfuscate.go

View workflow job for this annotation

GitHub Actions / sast / witness

result of fmt.Errorf call not used
}

obfuscateGlobList = append(obfuscateGlobList, obfuscateGlobCompiled)
}
}

for key, v := range variables {
val := v

if _, inObfuscateList := obfuscateList[key]; inObfuscateList {
val = "******"
}

for _, glob := range obfuscateGlobList {
if glob.Match(key) {
val = "******"
}
}

onAllowed(key, val, v)
}
}

0 comments on commit 9659a8c

Please sign in to comment.