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/../../biese și el din director; foloseșteIsLocal.
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.