Merge pull request #26555 from hashicorp/pselle/sensitive-var-value-compat

Avoid disclosing values in errors on marked vals
This commit is contained in:
Pam Selle 2020-10-13 10:51:25 -04:00 committed by GitHub
commit fcae49611c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 14 deletions

View File

@ -51,18 +51,17 @@ func assertObjectCompatible(schema *configschema.Block, planned, actual cty.Valu
actualV := actual.GetAttr(name) actualV := actual.GetAttr(name)
path := append(path, cty.GetAttrStep{Name: name}) path := append(path, cty.GetAttrStep{Name: name})
// If our value is marked, unmark it here before
// checking value assertions // Unmark values here before checking value assertions,
unmarkedActualV := actualV // but save the marks so we can see if we should supress
if actualV.ContainsMarked() { // exposing a value through errors
unmarkedActualV, _ = actualV.UnmarkDeep() unmarkedActualV, marksA := actualV.UnmarkDeep()
} unmarkedPlannedV, marksP := plannedV.UnmarkDeep()
unmarkedPlannedV := plannedV _, isMarkedActual := marksA["sensitive"]
if plannedV.ContainsMarked() { _, isMarkedPlanned := marksP["sensitive"]
unmarkedPlannedV, _ = actualV.UnmarkDeep()
}
moreErrs := assertValueCompatible(unmarkedPlannedV, unmarkedActualV, path) moreErrs := assertValueCompatible(unmarkedPlannedV, unmarkedActualV, path)
if attrS.Sensitive { if attrS.Sensitive || isMarkedActual || isMarkedPlanned {
if len(moreErrs) > 0 { if len(moreErrs) > 0 {
// Use a vague placeholder message instead, to avoid disclosing // Use a vague placeholder message instead, to avoid disclosing
// sensitive information. // sensitive information.
@ -73,9 +72,8 @@ func assertObjectCompatible(schema *configschema.Block, planned, actual cty.Valu
} }
} }
for name, blockS := range schema.BlockTypes { for name, blockS := range schema.BlockTypes {
// Unmark values before testing compatibility plannedV, _ := planned.GetAttr(name).Unmark()
plannedV, _ := planned.GetAttr(name).UnmarkDeep() actualV, _ := actual.GetAttr(name).Unmark()
actualV, _ := actual.GetAttr(name).UnmarkDeep()
// As a special case, if there were any blocks whose leaf attributes // As a special case, if there were any blocks whose leaf attributes
// are all unknown then we assume (possibly incorrectly) that the // are all unknown then we assume (possibly incorrectly) that the

View File

@ -144,6 +144,56 @@ func TestAssertObjectCompatible(t *testing.T) {
`.name: inconsistent values for sensitive attribute`, `.name: inconsistent values for sensitive attribute`,
}, },
}, },
{
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"id": {
Type: cty.String,
Computed: true,
},
"name": {
Type: cty.String,
Required: true,
},
},
},
cty.ObjectVal(map[string]cty.Value{
"id": cty.UnknownVal(cty.String),
"name": cty.StringVal("wotsit").Mark("sensitive"),
}),
cty.ObjectVal(map[string]cty.Value{
"id": cty.UnknownVal(cty.String),
"name": cty.StringVal("thingy"),
}),
[]string{
`.name: inconsistent values for sensitive attribute`,
},
},
{
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"id": {
Type: cty.String,
Computed: true,
},
"name": {
Type: cty.String,
Required: true,
},
},
},
cty.ObjectVal(map[string]cty.Value{
"id": cty.UnknownVal(cty.String),
"name": cty.StringVal("wotsit"),
}),
cty.ObjectVal(map[string]cty.Value{
"id": cty.UnknownVal(cty.String),
"name": cty.StringVal("thingy").Mark("sensitive"),
}),
[]string{
`.name: inconsistent values for sensitive attribute`,
},
},
{ {
&configschema.Block{ &configschema.Block{
Attributes: map[string]*configschema.Attribute{ Attributes: map[string]*configschema.Attribute{