During the ongoing work on the TUF conformance test suite, we have come across a test that reveals what we believe is a bug in go-tuf with security implications. The bug exists in go-tuf delegation tracing and could result in downloading the wrong artifact.
We have come across this issue in the test in this PR: theupdateframework/tuf-conformance#115.
The test - test_graph_traversal
- sets up a repository with a series of delegations, invokes the clients refresh()
and then checks the order in which the client traced the delegations. The test shows that the go-tuf client inconsistently traces the delegations in a wrong way. For example, during one CI run, the two-level-delegations
test case triggered a wrong order. The delegations in this look as such:
"two-level-delegations": DelegationsTestCase(
delegations=[
DelegationTester("targets", "A"),
DelegationTester("targets", "B"),
DelegationTester("B", "C"),
],
visited_order=["A", "B", "C"],
),
Here, targets
delegate to "A"
, and to "B"
, and "B"
delegates to "C"
. The client should trace the delegations in the order "A"
then "B"
then "C"
but in this particular CI run, go-tuf traced the delegations "B"->"C"->"A"
.
In a subsequent CI run, this test case did not fail, but another one did.
@jku has done a bit of debugging and believes that the returned map of GetRolesForTarget
returns a map that causes this behavior:
|
func (role *Delegations) GetRolesForTarget(targetFilepath string) map[string]bool { |
|
res := map[string]bool{} |
|
// standard delegations |
|
if role.Roles != nil { |
|
for _, r := range role.Roles { |
|
ok, err := r.IsDelegatedPath(targetFilepath) |
|
if err == nil && ok { |
|
res[r.Name] = r.Terminating |
|
} |
|
} |
|
} else if role.SuccinctRoles != nil { |
|
// SuccinctRoles delegations |
|
res = role.SuccinctRoles.GetRolesForTarget(targetFilepath) |
|
} |
|
return res |
|
} |
We believe that this map should be an ordered list instead of a map.
During the ongoing work on the TUF conformance test suite, we have come across a test that reveals what we believe is a bug in go-tuf with security implications. The bug exists in go-tuf delegation tracing and could result in downloading the wrong artifact.
We have come across this issue in the test in this PR: theupdateframework/tuf-conformance#115.
The test -
test_graph_traversal
- sets up a repository with a series of delegations, invokes the clientsrefresh()
and then checks the order in which the client traced the delegations. The test shows that the go-tuf client inconsistently traces the delegations in a wrong way. For example, during one CI run, thetwo-level-delegations
test case triggered a wrong order. The delegations in this look as such:Here,
targets
delegate to"A"
, and to"B"
, and"B"
delegates to"C"
. The client should trace the delegations in the order"A"
then"B"
then"C"
but in this particular CI run, go-tuf traced the delegations"B"->"C"->"A"
.In a subsequent CI run, this test case did not fail, but another one did.
@jku has done a bit of debugging and believes that the returned map of
GetRolesForTarget
returns a map that causes this behavior:go-tuf/metadata/metadata.go
Lines 565 to 580 in f95222b
We believe that this map should be an ordered list instead of a map.