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

Ouverte
#22,214 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
50/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Calme
Stack technique
go
Domaine
security

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.

Description

question

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
Langage dominant
CodeQL
Étoiles
10.1k
Forks
2.1k
Merge moyen
2 j 11 h
PR mergées (30 j)
129

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de github/codeql

Toutes les issues de github/codeql

Issues similaires

Plus d'issues Security

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.