Skip to content

Commit

Permalink
Added some tests for censoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
fbarl committed Feb 23, 2019
1 parent c5022bd commit 353ab75
Show file tree
Hide file tree
Showing 8 changed files with 390 additions and 41 deletions.
45 changes: 25 additions & 20 deletions render/detailed/censor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,45 @@ import (
"github.com/weaveworks/scope/report"
)

func censorNodeSummary(s *NodeSummary, cfg report.CensorConfig) {
if cfg.HideCommandLineArguments {
func censorNodeSummary(s NodeSummary, cfg report.CensorConfig) NodeSummary {
if cfg.HideCommandLineArguments && s.Metadata != nil {
// Iterate through all the metadata rows and strip the
// arguments from all the values containing a command.
for index := range s.Metadata {
row := &s.Metadata[index]
// arguments from all the values containing a command
// (while making sure everything is done in a non-mutable way).
metadata := []report.MetadataRow{}
for _, row := range s.Metadata {
if report.IsCommandEntry(row.ID) {
row.Value = report.StripCommandArgs(row.Value)
}
metadata = append(metadata, row)
}
s.Metadata = metadata
}
if cfg.HideEnvironmentVariables {
// Go through all the tables and if environment variables
// table is found, drop it from the list and stop the loop.
for index, table := range s.Tables {
if report.IsEnvironmentVarsEntry(table.ID) {
s.Tables = append(s.Tables[:index], s.Tables[index+1:]...)
break
if cfg.HideEnvironmentVariables && s.Tables != nil {
// Copy across all the tables except the environment
// variable ones (ensuring the operation is non-mutable).
tables := []report.Table{}
for _, table := range s.Tables {
if !report.IsEnvironmentVarsEntry(table.ID) {
tables = append(tables, table)
}
}
s.Tables = tables
}
return s
}

// CensorNode removes any sensitive data from a node.
func CensorNode(n Node, cfg report.CensorConfig) Node {
censorNodeSummary(&n.NodeSummary, cfg)
return n
func CensorNode(node Node, cfg report.CensorConfig) Node {
node.NodeSummary = censorNodeSummary(node.NodeSummary, cfg)
return node
}

// CensorNodeSummaries removes any sensitive data from a list of node summaries.
func CensorNodeSummaries(ns NodeSummaries, cfg report.CensorConfig) NodeSummaries {
for key, summary := range ns {
censorNodeSummary(&summary, cfg)
ns[key] = summary
func CensorNodeSummaries(summaries NodeSummaries, cfg report.CensorConfig) NodeSummaries {
censored := NodeSummaries{}
for key := range summaries {
censored[key] = censorNodeSummary(summaries[key], cfg)
}
return ns
return censored
}
228 changes: 228 additions & 0 deletions render/detailed/censor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
package detailed_test

import (
"reflect"
"testing"

"github.com/weaveworks/common/test"
"github.com/weaveworks/scope/render/detailed"
"github.com/weaveworks/scope/report"
)

func TestCensorNode(t *testing.T) {
node := detailed.Node{
NodeSummary: detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog -a --b=c"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
{ID: "docker_env_", Rows: []report.Row{{ID: "env_var"}}},
},
},
}

for _, c := range []struct {
label string
have, want detailed.Node
}{
{
label: "no censoring",
have: detailed.CensorNode(node, report.CensorConfig{
HideCommandLineArguments: false,
HideEnvironmentVariables: false,
}),
want: detailed.Node{
NodeSummary: detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog -a --b=c"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
{ID: "docker_env_", Rows: []report.Row{{ID: "env_var"}}},
},
},
},
},
{
label: "censor only command line args",
have: detailed.CensorNode(node, report.CensorConfig{
HideCommandLineArguments: true,
HideEnvironmentVariables: false,
}),
want: detailed.Node{
NodeSummary: detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
{ID: "docker_env_", Rows: []report.Row{{ID: "env_var"}}},
},
},
},
},
{
label: "censor only env variables",
have: detailed.CensorNode(node, report.CensorConfig{
HideCommandLineArguments: false,
HideEnvironmentVariables: true,
}),
want: detailed.Node{
NodeSummary: detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog -a --b=c"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
},
},
},
},
{
label: "censor both command line args and env vars",
have: detailed.CensorNode(node, report.CensorConfig{
HideCommandLineArguments: true,
HideEnvironmentVariables: true,
}),
want: detailed.Node{
NodeSummary: detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
},
},
},
},
} {
if !reflect.DeepEqual(c.want, c.have) {
t.Errorf("%s - %s", c.label, test.Diff(c.want, c.have))
}
}
}

func TestCensorNodeSummaries(t *testing.T) {
summaries := detailed.NodeSummaries{
"a": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "blublu", Label: "blabla", Value: "blu blu"},
{ID: "docker_container_command", Label: "Command", Value: "scope --token=blibli"},
},
},
"b": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog -a --b=c"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
{ID: "docker_env_", Rows: []report.Row{{ID: "env_var"}}},
},
},
}

for _, c := range []struct {
label string
have, want detailed.NodeSummaries
}{
{
label: "no censoring",
have: detailed.CensorNodeSummaries(summaries, report.CensorConfig{
HideCommandLineArguments: false,
HideEnvironmentVariables: false,
}),
want: detailed.NodeSummaries{
"a": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "blublu", Label: "blabla", Value: "blu blu"},
{ID: "docker_container_command", Label: "Command", Value: "scope --token=blibli"},
},
},
"b": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog -a --b=c"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
{ID: "docker_env_", Rows: []report.Row{{ID: "env_var"}}},
},
},
},
},
{
label: "censor only command line args",
have: detailed.CensorNodeSummaries(summaries, report.CensorConfig{
HideCommandLineArguments: true,
HideEnvironmentVariables: false,
}),
want: detailed.NodeSummaries{
"a": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "blublu", Label: "blabla", Value: "blu blu"},
{ID: "docker_container_command", Label: "Command", Value: "scope"},
},
},
"b": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
{ID: "docker_env_", Rows: []report.Row{{ID: "env_var"}}},
},
},
},
},
{
label: "censor only env variables",
have: detailed.CensorNodeSummaries(summaries, report.CensorConfig{
HideCommandLineArguments: false,
HideEnvironmentVariables: true,
}),
want: detailed.NodeSummaries{
"a": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "blublu", Label: "blabla", Value: "blu blu"},
{ID: "docker_container_command", Label: "Command", Value: "scope --token=blibli"},
},
},
"b": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog -a --b=c"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
},
},
},
},
{
label: "censor both command line args and env vars",
have: detailed.CensorNodeSummaries(summaries, report.CensorConfig{
HideCommandLineArguments: true,
HideEnvironmentVariables: true,
}),
want: detailed.NodeSummaries{
"a": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "blublu", Label: "blabla", Value: "blu blu"},
{ID: "docker_container_command", Label: "Command", Value: "scope"},
},
},
"b": detailed.NodeSummary{
Metadata: []report.MetadataRow{
{ID: "cmdline", Label: "Command", Value: "prog"},
},
Tables: []report.Table{
{ID: "blibli", Rows: []report.Row{{ID: "bli"}}},
},
},
},
},
} {
if !reflect.DeepEqual(c.want, c.have) {
t.Errorf("%s - %s", c.label, test.Diff(c.want, c.have))
}
}
}
45 changes: 25 additions & 20 deletions report/censor.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ type CensorConfig struct {
// GetCensorConfigFromRequest extracts censor config from request query params.
func GetCensorConfigFromRequest(req *http.Request) CensorConfig {
return CensorConfig{
HideCommandLineArguments: true || req.URL.Query().Get("hideCommandLineArguments") == "true",
HideEnvironmentVariables: true || req.URL.Query().Get("hideEnvironmentVariables") == "true",
HideCommandLineArguments: req.URL.Query().Get("hideCommandLineArguments") == "true",
HideEnvironmentVariables: req.URL.Query().Get("hideEnvironmentVariables") == "true",
}
}

Expand All @@ -37,27 +37,32 @@ func StripCommandArgs(command string) string {
return strings.Split(command, " ")[0]
}

// CensorRawReport removes any sensitive data from
// the raw report based on the request query params.
func CensorRawReport(r Report, cfg CensorConfig) Report {
r.WalkTopologies(func(t *Topology) {
// CensorRawReport removes any sensitive data from the raw report based on the request query params.
func CensorRawReport(rawReport Report, cfg CensorConfig) Report {
// Create a copy of the report first to make sure the operation is immutable.
censoredReport := rawReport.Copy()
censoredReport.ID = rawReport.ID

censoredReport.WalkTopologies(func(t *Topology) {
for nodeID, node := range t.Nodes {
latest := StringLatestMap{}
for _, entry := range node.Latest {
// If environment variables are to be hidden, omit passing them to the final report.
if cfg.HideEnvironmentVariables && IsEnvironmentVarsEntry(entry.key) {
continue
}
// If command line arguments are to be hidden, strip them away.
if cfg.HideCommandLineArguments && IsCommandEntry(entry.key) {
entry.Value = StripCommandArgs(entry.Value)
if node.Latest != nil {
latest := make(StringLatestMap, 0, cap(node.Latest))
for _, entry := range node.Latest {
// If environment variables are to be hidden, omit passing them to the final report.
if cfg.HideEnvironmentVariables && IsEnvironmentVarsEntry(entry.key) {
continue
}
// If command line arguments are to be hidden, strip them away.
if cfg.HideCommandLineArguments && IsCommandEntry(entry.key) {
entry.Value = StripCommandArgs(entry.Value)
}
// Pass the latest entry to the final report.
latest = append(latest, entry)
}
// Pass the latest entry to the final report.
latest = append(latest, entry)
node.Latest = latest
t.Nodes[nodeID] = node
}
node.Latest = latest
t.Nodes[nodeID] = node
}
})
return r
return censoredReport
}
Loading

0 comments on commit 353ab75

Please sign in to comment.