filepath.IsLocal în Go

Spune dacă o cale rămâne în interiorul directorului curent: nu e absolută, nu e goală și nu urcă cu „..”.

Sintaxă
func IsLocal(path string) bool

Ce face filepath.IsLocal

filepath.IsLocal verifică dacă o cale, interpretată față de un director, rămâne în acel director. Returnează false pentru căi absolute, pentru calea goală, pentru căi care ies cu .. și, pe Windows, pentru nume rezervate ca NUL sau COM1.

Este verificarea potrivită pentru nume venite din afară: fișiere încărcate, intrări dintr-o arhivă zip, parametri dintr-un URL. Atacul „path traversal” (../../etc/passwd) este oprit. Verificarea este textuală; nu ține cont de legăturile simbolice.

Parametri

Parametru Descriere
path Calea de verificat.

Ce returnează

true dacă calea este locală.

Exemple

Exemplul 1: Căi locale și periculoase

package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    for _, c := range []string{"poza.jpg", "albume/vara.jpg", "a/../b.txt", "../secret.txt", "a/../../b", "/etc/passwd", ""} {
        fmt.Printf("%-18q %v\n", c, filepath.IsLocal(c))
    }
}

Rezultat

"poza.jpg"         true
"albume/vara.jpg"  true
"a/../b.txt"       true
"../secret.txt"    false
"a/../../b"        false
"/etc/passwd"      false
""                 false

Exemplul 2: Salvarea sigură a unui fișier încărcat

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func salveazaIncarcare(nume string, date []byte) error {
    if !filepath.IsLocal(nume) {
        return fmt.Errorf("nume de fișier refuzat: %q", nume)
    }
    cale := filepath.Join("uploads", nume)
    os.MkdirAll(filepath.Dir(cale), 0o755)
    return os.WriteFile(cale, date, 0o644)
}

func main() {
    fmt.Println(salveazaIncarcare("cv-ana.pdf", []byte("...")))
    fmt.Println(salveazaIncarcare("../../.ssh/authorized_keys", []byte("...")))
}

Rezultat

<nil>
nume de fișier refuzat: "../../.ssh/authorized_keys"

Greșeli frecvente

  • Verifici doar dacă numele începe cu ... a/../../b iese și el din director; folosește IsLocal.

Comenzi înrudite

  • filepath.Join: Unește mai multe bucăți într-o cale, cu separatorul corect al sistemului, și curăță rezultatul.
  • filepath.Localize: Transformă o cale cu „/” (ca în fs.FS sau URL) într-o cale locală a sistemului, refuzând căile nesigure.
  • filepath.Clean: Simplifică o cale: elimină separatoarele duble, „.” și rezolvă „..” doar din text, fără acces la disc.
  • os.RemoveAll: Șterge un fișier sau un director cu tot conținutul lui; nu dă eroare dacă nu există.
  • os.OpenRoot: Deschide un director ca rădăcină din care nu se poate ieși; OpenInRoot deschide un fișier strict în interiorul unui director.