Skip to content

Commit d8c108a

Browse files
authored
fix: prevent path traversal vulnerabilities by validating absolute paths in file unpacking and test utilities, and add workflow permissions. (#204)
1 parent 304c7ef commit d8c108a

4 files changed

Lines changed: 21 additions & 3 deletions

File tree

.github/workflows/go.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ on:
77
branches: [ master ]
88
schedule:
99
- cron: '0 0 * * 0' # weekly
10+
permissions:
11+
contents: read
1012

1113
jobs:
1214

download/download.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,12 @@ func ExtractPkg(src string) (dst string, err error) {
226226
}
227227

228228
name := filepath.Clean(header.Name)
229-
if strings.HasPrefix(name, ".."+string(os.PathSeparator)) {
229+
absDst, err := filepath.Abs(dst)
230+
if err != nil {
231+
return "", err
232+
}
233+
absPath := filepath.Join(absDst, name)
234+
if !strings.HasPrefix(absPath, absDst) {
230235
return "", fmt.Errorf("error unpacking package, file contains path traversal: %q", name)
231236
}
232237

googet.goospec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{{$version := "3.3.0@0" -}}
1+
{{$version := "3.3.1@0" -}}
22
{
33
"name": "googet",
44
"version": "{{$version}}",
@@ -15,6 +15,7 @@
1515
"path": "install.ps1"
1616
},
1717
"releaseNotes": [
18+
"3.3.1 - Fix: Prevent path traversal vulnerabilities in file unpacking and add workflow permissions.",
1819
"3.3.0 - Refactor: Update FindRepoLatest to prioritize repo priority, version, and architecture with lock support.",
1920
"3.3.0 - Refactor: Add file ownership conflict checks to prevent overwrites.",
2021
"3.2.1 - Refactor: Update GooDB.FetchPkg to accept goolib.PackageInfo.",

testutil/testutil.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"net/http/httptest"
1313
"os"
1414
"path/filepath"
15+
"strings"
1516
"testing"
1617
"time"
1718

@@ -65,7 +66,16 @@ func GenGoo(t *testing.T, dir, dst string, ps goolib.PkgSpec) goolib.RepoSpec {
6566
func ServeGoo(t *testing.T, dir string) *httptest.Server {
6667
t.Helper()
6768
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
68-
f, err := os.Open(filepath.Join(dir, r.URL.Path))
69+
absDir, err := filepath.Abs(dir)
70+
if err != nil {
71+
t.Fatal(err)
72+
}
73+
absPath, err := filepath.Abs(filepath.Join(absDir, r.URL.Path))
74+
if err != nil || !strings.HasPrefix(absPath, absDir) {
75+
http.Error(w, "Invalid file name", http.StatusBadRequest)
76+
return
77+
}
78+
f, err := os.Open(absPath)
6979
if err != nil {
7080
t.Logf("couldn't find file: %v", r.URL.Path)
7181
http.Error(w, "couldn't find requested file", http.StatusNotFound)

0 commit comments

Comments
 (0)