Skip to content

Commit

Permalink
bug: fix incorrect policy evaluation
Browse files Browse the repository at this point in the history
Attestation collections were incorrectly being considered to have passed
the policy if any of the attestations passed, even if others failed.
This was due to the collection being added to the Passed slice multiple
times for each attestation that didn't result in a failure.  Properly
breaking out of the inner loop and only considering a collection as
passed when all of it's attestations pass fixes the issue.

Signed-off-by: Mikhail Swift <[email protected]>
  • Loading branch information
mikhailswift authored and colek42 committed Feb 4, 2022
1 parent 124eea9 commit b0b7167
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 44 deletions.
2 changes: 1 addition & 1 deletion examples/log4shell/verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ printf "\nVerifying policy on nonvulnerable package...\n"
docker run --rm -it --net host -v "$(pwd):/src" -w /src/nonvuln witness-log4shell-demo witness verify -c ../witness.yaml --artifactfile target/my-app-1.0-SNAPSHOT.jar

printf "\nVerifying policy on vulnerable package...\n"
docker run --rm -it --net host -v "$(pwd):/src" -w /src/vuln witness-log4shell-demo witness verify -c ../witness.yaml -a ./demo-attestation.json --artifactfile target/my-app-1.0-SNAPSHOT.jar
docker run --rm -it --net host -v "$(pwd):/src" -w /src/vuln witness-log4shell-demo witness verify -c ../witness.yaml --artifactfile target/my-app-1.0-SNAPSHOT.jar

43 changes: 43 additions & 0 deletions pkg/policy/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ package policy

import (
"fmt"
"strings"
"time"

"github.com/testifysec/witness/pkg/cryptoutil"
)

type ErrNoAttestations string
Expand Down Expand Up @@ -48,3 +51,43 @@ type ErrKeyIDMismatch struct {
func (e ErrKeyIDMismatch) Error() string {
return fmt.Sprintf("public key in policy has expected key id %v but got %v", e.Expected, e.Actual)
}

type ErrUnknownStep string

func (e ErrUnknownStep) Error() string {
return fmt.Sprintf("policy has no step named %v", string(e))
}

type ErrArtifactCycle string

func (e ErrArtifactCycle) Error() string {
return fmt.Sprintf("cycle detected in step's artifact dependencies: %v", string(e))
}

type ErrMismatchArtifact struct {
Artifact cryptoutil.DigestSet
Material cryptoutil.DigestSet
Path string
}

func (e ErrMismatchArtifact) Error() string {
return fmt.Sprintf("mismatched digests for %v", e.Path)
}

type ErrRegoInvalidData struct {
Path string
Expected string
Actual interface{}
}

func (e ErrRegoInvalidData) Error() string {
return fmt.Sprintf("invalid data from rego at %v, expected %v but got %T", e.Path, e.Expected, e.Actual)
}

type ErrPolicyDenied struct {
Reasons []string
}

func (e ErrPolicyDenied) Error() string {
return fmt.Sprintf("policy was denied due to:\n%v", strings.Join(e.Reasons, "\n -"))
}
22 changes: 0 additions & 22 deletions pkg/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,25 +280,3 @@ func compareArtifacts(mats map[string]cryptoutil.DigestSet, arts map[string]cryp

return nil
}

type ErrUnknownStep string

func (e ErrUnknownStep) Error() string {
return fmt.Sprintf("policy has no step named %v", string(e))
}

type ErrArtifactCycle string

func (e ErrArtifactCycle) Error() string {
return fmt.Sprintf("cycle detected in step's artifact dependencies: %v", string(e))
}

type ErrMismatchArtifact struct {
Artifact cryptoutil.DigestSet
Material cryptoutil.DigestSet
Path string
}

func (e ErrMismatchArtifact) Error() string {
return fmt.Sprintf("mismatched digests for %v", e.Path)
}
19 changes: 0 additions & 19 deletions pkg/policy/rego.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,12 @@ import (
"context"
"encoding/json"
"fmt"
"strings"

"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/rego"
"github.com/testifysec/witness/pkg/attestation"
)

type ErrRegoInvalidData struct {
Path string
Expected string
Actual interface{}
}

func (e ErrRegoInvalidData) Error() string {
return fmt.Sprintf("invalid data from rego at %v, expected %v but got %T", e.Path, e.Expected, e.Actual)
}

type ErrPolicyDenied struct {
Reasons []string
}

func (e ErrPolicyDenied) Error() string {
return fmt.Sprintf("policy was denied due to:\n%v", strings.Join(e.Reasons, "\n -"))
}

func EvaluateRegoPolicy(attestor attestation.Attestor, policies []RegoPolicy) error {
if len(policies) == 0 {
return nil
Expand Down
9 changes: 7 additions & 2 deletions pkg/policy/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (s Step) validateAttestations(attestCollections []attestation.Collection) S
found[attestation.Type] = attestation.Attestation
}

passed := true
for _, expected := range s.Attestations {
attestor, ok := found[expected.Type]
if !ok {
Expand All @@ -104,7 +105,8 @@ func (s Step) validateAttestations(attestCollections []attestation.Collection) S
},
})

continue
passed = false
break
}

if err := EvaluateRegoPolicy(attestor, expected.RegoPolicies); err != nil {
Expand All @@ -113,9 +115,12 @@ func (s Step) validateAttestations(attestCollections []attestation.Collection) S
Reason: err,
})

continue
passed = false
break
}
}

if passed {
result.Passed = append(result.Passed, collection)
}
}
Expand Down

0 comments on commit b0b7167

Please sign in to comment.