Go: Why is DotDotCheck modeled as a complete path-injection barrier?
- Langage dominant
- CodeQL
- Étoiles
- 10.1k
- Forks
- 2.1k
- Merge moyen
- 2 j 15 h
- PR mergées (30 j)
- 141
Description
**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**
```go
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
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par DotDotCheck dans TaintedPathCustomizations.qll (lignes 106-122), puis examinez le cas GOOD à la ligne 31 de TaintedPath.go ainsi que les tests de la requête d’injection de chemin Go. Vérifiez comment la branche false devient un isBarrier via SanitizerGuardAsSanitizer, et comparez le comportement attendu avec les indications de filepath.Base. Le travail est terminé lorsque le modèle et les attentes des tests concernés reflètent de manière cohérente la protection prise en charge contre la traversée de chemins.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- go
- Domaine
- security
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 50/100