Skip to content

Go: Why is DotDotCheck modeled as a complete path-injection barrier? #22214

Description

@wildoranges

Description of the issue

The Go go/path-injection query treats !strings.Contains(path, "..") as a complete path-injection sanitizer. This means that when Contains returns false, taint is fully blocked - no additional sanitizer is required.

I'm wondering why this is modeled as a complete barrier, because checking for the absence of ".." does not prevent absolute-path attacks. For example, /etc/passwd does not contain "..", passes the guard, and can read files outside any intended directory.

The query help seems to agree - it says this approach is "only suitable if the input is expected to be a single file name", and also warns that user-controlled paths "may be absolute paths". But DotDotCheck doesn't distinguish between single-component inputs and multi-component paths.

The existing test case at TaintedPath.go line 31 marks this pattern as GOOD with the comment "This can only read inside the provided safe path", but tainted_path = "/etc/passwd" would still pass the check and escape any safe path.

Affected sanitizer

DotDotCheck in TaintedPathCustomizations.qll (lines 106-122) matches strings.Contains(p, "..") and declares the false branch as a complete sanitizer guard. Through SanitizerGuardAsSanitizer, this becomes a full isBarrier node.

Steps to reproduce

func handler(w http.ResponseWriter, r *http.Request) {
    p := r.URL.Query().Get("file")
    if !strings.Contains(p, "..") {
        data, _ := ioutil.ReadFile(p)  // 0 alerts with DotDotCheck enabled
        w.Write(data)
    }
}

Question

Given that !strings.Contains(p, "..") only blocks one specific attack vector and not absolute paths, would it be more appropriate to model it as a non-barrier (or at least not a complete one), similar to how filepath.Base is documented as "not a sanitizer for path traversal" in mime.multipart.model.yml?

Environment

  • CodeQL CLI 2.25.6
  • CodeQL repository commit: f6f45d1536312f53eed079868e344a5906bf3d72
  • Go 1.22.12 on Linux/amd64

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