Skip to content

Commit c82e632

Browse files
hshpyxhofe
andauthored
fix: potential XSS vulnerabilities (#7923)
* fix: potential XSS vulnerabilities * feat: support filter and render for readme.md * chore: set ReadMeAutoRender to true * fix attachFileName undefined --------- Co-authored-by: Andy Hsu <[email protected]>
1 parent 04f5525 commit c82e632

File tree

5 files changed

+82
-2
lines changed

5 files changed

+82
-2
lines changed

go.mod

+4
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ require (
8383

8484
require (
8585
github.com/STARRY-S/zip v0.2.1 // indirect
86+
github.com/aymerick/douceur v0.2.0 // indirect
8687
github.com/blevesearch/go-faiss v1.0.20 // indirect
8788
github.com/blevesearch/zapx/v16 v16.1.5 // indirect
8889
github.com/bodgit/plumbing v1.3.0 // indirect
@@ -97,6 +98,7 @@ require (
9798
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
9899
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
99100
github.com/fclairamb/go-log v0.5.0 // indirect
101+
github.com/gorilla/css v1.0.1 // indirect
100102
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
101103
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
102104
github.com/hekmon/cunits/v2 v2.1.0 // indirect
@@ -105,11 +107,13 @@ require (
105107
github.com/klauspost/pgzip v1.2.6 // indirect
106108
github.com/kr/text v0.2.0 // indirect
107109
github.com/matoous/go-nanoid/v2 v2.1.0 // indirect
110+
github.com/microcosm-cc/bluemonday v1.0.27
108111
github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78 // indirect
109112
github.com/sorairolake/lzip-go v0.3.5 // indirect
110113
github.com/taruti/bytepool v0.0.0-20160310082835-5e3a9ea56543 // indirect
111114
github.com/therootcompany/xz v1.0.1 // indirect
112115
github.com/ulikunitz/xz v0.5.12 // indirect
116+
github.com/yuin/goldmark v1.7.8
113117
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
114118
)
115119

go.sum

+8
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE
6868
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
6969
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
7070
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
71+
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
72+
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
7173
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
7274
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
7375
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -303,6 +305,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
303305
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
304306
github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA=
305307
github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc=
308+
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
309+
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
306310
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
307311
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
308312
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -424,6 +428,8 @@ github.com/meilisearch/meilisearch-go v0.27.2 h1:3G21dJ5i208shnLPDsIEZ0L0Geg/5oe
424428
github.com/meilisearch/meilisearch-go v0.27.2/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
425429
github.com/mholt/archives v0.1.0 h1:FacgJyrjiuyomTuNA92X5GyRBRZjE43Y/lrzKIlF35Q=
426430
github.com/mholt/archives v0.1.0/go.mod h1:j/Ire/jm42GN7h90F5kzj6hf6ZFzEH66de+hmjEKu+I=
431+
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
432+
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
427433
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
428434
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
429435
github.com/minio/sio v0.4.0 h1:u4SWVEm5lXSqU42ZWawV0D9I5AZ5YMmo2RXpEQ/kRhc=
@@ -613,6 +619,8 @@ github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9/go.mod h1:9BnoKCcgJ/+SLhf
613619
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
614620
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
615621
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
622+
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
623+
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
616624
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
617625
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
618626
github.com/zzzhr1990/go-common-entity v0.0.0-20221216044934-fd1c571e3a22 h1:X+lHsNTlbatQ1cErXIbtyrh+3MTWxqQFS+sBP/wpFXo=

internal/bootstrap/data/setting.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package data
22

33
import (
4+
"strconv"
5+
46
"github.com/alist-org/alist/v3/cmd/flags"
57
"github.com/alist-org/alist/v3/internal/conf"
68
"github.com/alist-org/alist/v3/internal/db"
@@ -11,7 +13,6 @@ import (
1113
"github.com/alist-org/alist/v3/pkg/utils/random"
1214
"github.com/pkg/errors"
1315
"gorm.io/gorm"
14-
"strconv"
1516
)
1617

1718
var initialSettingItems []model.SettingItem
@@ -141,6 +142,8 @@ func InitialSettings() []model.SettingItem {
141142
{Key: conf.AudioAutoplay, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
142143
{Key: conf.VideoAutoplay, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
143144
{Key: conf.PreviewArchivesByDefault, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
145+
{Key: conf.ReadMeAutoRender, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
146+
{Key: conf.FilterReadMeScripts, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
144147
// global settings
145148
{Key: conf.HideFiles, Value: "/\\/README.md/i", Type: conf.TypeText, Group: model.GLOBAL},
146149
{Key: "package_download", Value: "true", Type: conf.TypeBool, Group: model.GLOBAL},

internal/conf/const.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ const (
3131
AudioAutoplay = "audio_autoplay"
3232
VideoAutoplay = "video_autoplay"
3333
PreviewArchivesByDefault = "preview_archives_by_default"
34-
34+
ReadMeAutoRender = "readme_autorender"
35+
FilterReadMeScripts = "filter_readme_scripts"
3536
// global
3637
HideFiles = "hide_files"
3738
CustomizeHead = "customize_head"

server/common/proxy.go

+64
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,87 @@
11
package common
22

33
import (
4+
"bytes"
45
"context"
56
"fmt"
67
"io"
78
"net/http"
89
"net/url"
910
"os"
11+
"strconv"
1012
"strings"
1113

14+
"github.com/alist-org/alist/v3/internal/conf"
1215
"github.com/alist-org/alist/v3/internal/model"
1316
"github.com/alist-org/alist/v3/internal/net"
17+
"github.com/alist-org/alist/v3/internal/setting"
1418
"github.com/alist-org/alist/v3/internal/stream"
1519
"github.com/alist-org/alist/v3/pkg/http_range"
1620
"github.com/alist-org/alist/v3/pkg/utils"
21+
"github.com/microcosm-cc/bluemonday"
1722
log "github.com/sirupsen/logrus"
23+
"github.com/yuin/goldmark"
1824
)
1925

26+
func processMarkdown(content []byte) ([]byte, error) {
27+
var buf bytes.Buffer
28+
if err := goldmark.New().Convert(content, &buf); err != nil {
29+
return nil, fmt.Errorf("markdown conversion failed: %w", err)
30+
}
31+
return bluemonday.UGCPolicy().SanitizeBytes(buf.Bytes()), nil
32+
}
33+
2034
func Proxy(w http.ResponseWriter, r *http.Request, link *model.Link, file model.Obj) error {
35+
36+
//优先处理md文件
37+
if utils.Ext(file.GetName()) == "md" && setting.GetBool(conf.FilterReadMeScripts) {
38+
var markdownContent []byte
39+
var err error
40+
41+
if link.MFile != nil {
42+
defer link.MFile.Close()
43+
attachHeader(w, file)
44+
markdownContent, err = io.ReadAll(link.MFile)
45+
if err != nil {
46+
return fmt.Errorf("failed to read markdown content: %w", err)
47+
}
48+
49+
} else {
50+
header := net.ProcessHeader(r.Header, link.Header)
51+
res, err := net.RequestHttp(r.Context(), r.Method, header, link.URL)
52+
if err != nil {
53+
return err
54+
}
55+
defer res.Body.Close()
56+
for h, v := range res.Header {
57+
w.Header()[h] = v
58+
}
59+
w.WriteHeader(res.StatusCode)
60+
if r.Method == http.MethodHead {
61+
return nil
62+
}
63+
markdownContent, err = io.ReadAll(res.Body)
64+
if err != nil {
65+
return fmt.Errorf("failed to read markdown content: %w", err)
66+
}
67+
68+
}
69+
70+
safeHTML, err := processMarkdown(markdownContent)
71+
if err != nil {
72+
return err
73+
}
74+
75+
safeHTMLReader := bytes.NewReader(safeHTML)
76+
w.Header().Set("Content-Length", strconv.FormatInt(int64(len(safeHTML)), 10))
77+
w.Header().Set("Content-Type", "text/html; charset=utf-8")
78+
_, err = utils.CopyWithBuffer(w, safeHTMLReader)
79+
if err != nil {
80+
return err
81+
}
82+
return nil
83+
}
84+
2185
if link.MFile != nil {
2286
defer link.MFile.Close()
2387
attachHeader(w, file)

0 commit comments

Comments
 (0)