Skip to content

Go: Tainted data does not propagate data flow after append function #14116

@Jokuuy

Description

@Jokuuy

Go: v1.19.1 linux/amd64
CodeQL: v2.11.0

Question: Query the data flow results from the input parameter in the source function to the name parameter in the sink function.

package main

import (
	"fmt"
)

type info struct {
	name string
}
func main() {
	source("input")
}

func source(input string) {
	var data []info
	data = append(data, info{
		name: input,
	})
	dao(data)

}

func dao(data []info) {
	for _, item := range data {
		name := item.name
		sink(name)
	}
}

func sink(name string) {
	fmt.Println(name)
}

The following is my query statement. After execution, I did not get the expected results.

append_struct_result
/**
 * @kind path-problem
 */

import go
import DataFlow::PathGraph

class Configuration extends TaintTracking::Configuration {
  Configuration() { this = "Configuration" }

  override predicate isSource(DataFlow::Node source) {
    exists(Function func | func.getName() = "source" | func.getParameter(0) = source.asParameter())
  }

  override predicate isSink(DataFlow::Node sink) {
    exists(DataFlow::CallNode call | call.getTarget().getName() = "sink" |
      call.getArgument(0) = sink
    )
  }
}

from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Source: $@ , Sink: $@ .", source.getNode(), source.toString(),
  sink.getNode(), sink.toString()

When I debug using DataFlow::PartialPathGraph, it seems that the tainted data does not propagate the data flow after passing through the append function.

append_struct_partial
/**
 * @kind path-problem
 */

import go
import DataFlow::PartialPathGraph

class Configuration extends TaintTracking::Configuration {
  Configuration() { this = "Configuration" }

  override predicate isSource(DataFlow::Node source) {
    exists(Function func | func.getName() = "source" | func.getParameter(0) = source.asParameter())
  }

  override predicate isSink(DataFlow::Node sink) {
    exists(DataFlow::CallNode call | call.getTarget().getName() = "sink" |
      call.getArgument(0) = sink
    )
  }

  override int explorationLimit() { result = 5 }
}

from Configuration cfg, DataFlow::PartialPathNode source, DataFlow::PartialPathNode sink
where cfg.hasPartialFlow(source, sink, _)
select sink.getNode(), source, sink, "Source: $@ , Sink: $@ .", source.getNode(), source.toString(), sink.getNode(), sink.toString()

How to solve this problem?

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions