@@ -125,12 +125,44 @@ func (d *FSPluginDecoder) Close() error {
125125 return nil
126126}
127127
128+ func ensureUnderRoot (root , name string ) (string , error ) {
129+ p := filepath .Join (root , filepath .FromSlash (name ))
130+ clean := filepath .Clean (p )
131+ rootAbs , err := filepath .Abs (root )
132+ if err != nil {
133+ return "" , err
134+ }
135+ cleanAbs , err := filepath .Abs (clean )
136+ if err != nil {
137+ return "" , err
138+ }
139+ rel , err := filepath .Rel (rootAbs , cleanAbs )
140+ if err != nil {
141+ return "" , err
142+ }
143+ if rel == "." {
144+ return cleanAbs , nil
145+ }
146+ if strings .HasPrefix (rel , ".." ) {
147+ return "" , os .ErrPermission
148+ }
149+ return cleanAbs , nil
150+ }
151+
128152func (d * FSPluginDecoder ) Stat (filename string ) (fs.FileInfo , error ) {
129- return os .Stat (filepath .Join (d .root , filename ))
153+ abs , err := ensureUnderRoot (d .root , filename )
154+ if err != nil {
155+ return nil , err
156+ }
157+ return os .Stat (abs )
130158}
131159
132160func (d * FSPluginDecoder ) ReadFile (filename string ) ([]byte , error ) {
133- return os .ReadFile (filepath .Join (d .root , filename ))
161+ abs , err := ensureUnderRoot (d .root , filename )
162+ if err != nil {
163+ return nil , err
164+ }
165+ return os .ReadFile (abs )
134166}
135167
136168func (d * FSPluginDecoder ) ReadDir (dirname string ) ([]string , error ) {
@@ -158,7 +190,11 @@ func (d *FSPluginDecoder) ReadDir(dirname string) ([]string, error) {
158190}
159191
160192func (d * FSPluginDecoder ) FileReader (filename string ) (io.ReadCloser , error ) {
161- return os .Open (filepath .Join (d .root , filename ))
193+ abs , err := ensureUnderRoot (d .root , filename )
194+ if err != nil {
195+ return nil , err
196+ }
197+ return os .Open (abs )
162198}
163199
164200func (d * FSPluginDecoder ) Signature () (string , error ) {
0 commit comments