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

Filtering types at call edges to handle tuples better. #128

Open
wants to merge 1 commit into
base: mainline
Choose a base branch
from
Open
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
13 changes: 13 additions & 0 deletions analysis/dataflow/code_identifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package dataflow

import (
"go/token"
"go/types"

"github.com/awslabs/ar-go-tools/analysis/annotations"
"github.com/awslabs/ar-go-tools/analysis/config"
Expand Down Expand Up @@ -126,6 +127,18 @@ func IsFiltered(s *State, ts *config.TaintSpec, n GraphNode) bool {
return false
}

// IsFilteredType returns true if the type is filtered out by the taint analysis specification.
func IsFilteredType(ts *config.TaintSpec, t types.Type) bool {
for _, filter := range ts.Filters {
if filter.Type != "" {
if filter.MatchType(t) {
return true
}
}
}
return false
}

func isMatchingCodeID(codeIDOracle func(config.CodeIdentifier) bool, n GraphNode) bool {
switch n := n.(type) {
case *ParamNode, *FreeVarNode:
Expand Down
5 changes: 5 additions & 0 deletions analysis/taint/dataflow_visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,11 @@ func (v *Visitor) Visit(s *df.State, source df.NodeWithTrace) {
}
for nextNode, edgeInfos := range graphNode.Out() {
for _, edgeInfo := range edgeInfos {
// Filter outgoing edges with a type that is filtered by checking the index of the tuple
// The index is an edge property so we can't rely on the node being filtered out.
if df.IsFilteredType(v.taintSpec, lang.TryTupleIndexType(graphNode.Type(), edgeInfo.Index)) {
continue
}
nextNodeWithTrace := df.NodeWithTrace{
Node: nextNode,
Trace: trace,
Expand Down
3 changes: 3 additions & 0 deletions analysis/taint/testdata/filters/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ dataflow-problems:
- package: "(filters)|(main)|(command-line-arguments)|(git.amazon.com[[:graph:]]*)$"
# Sources can be source1, source2, etc.
method: "source[1-9]?"
- package: "(filters)|(main)|(command-line-arguments)|(git.amazon.com[[:graph:]]*)$"
# Sources can be source1, source2, etc.
method: "sourceErr"
sinks:
- package: "(filters)|(main)|(command-line-arguments)|(git.amazon.com[[:graph:]]*)$"
# Similarly, sinks are sink1 sink2 sink2 ...
Expand Down
19 changes: 18 additions & 1 deletion analysis/taint/testdata/filters/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ func generateWithError() (string, error) {
}
}

func sourceError() (string, error) {
if rand.Int() > 20 {
return fmt.Sprintf("x-%d", rand.Int()), nil
} else {
return "ok", fmt.Errorf("generation failure")
}
}

func generateWithFlag() (string, bool) {
if rand.Int() > 20 {
return source(), false // @Source(gBool)
Expand All @@ -55,6 +63,15 @@ func testErrorFiltered() {
sink(s) // sanitized
}

// the config contains:
// filters:
// - type: "error"
func testErrorFilteredImmediate() {
s, e := sourceError() // @Source(sourceErr)
sink(e) // error is filtered out
sink(s) // @Sink(sourceErr)
}

// the config contains:
// filters:
// - type: "bool"
Expand All @@ -80,7 +97,7 @@ func doSth2(b bool, s string) {
func main() {
testErrorFiltered()
testBoolFiltered()

testErrorFilteredImmediate()
}

func sink(_ ...any) {
Expand Down
Loading