mirror of
https://github.com/projectdiscovery/nuclei
synced 2026-06-08 16:50:47 +00:00
20cbf0bd73
* feat(filepath): add IsPathWithinAnyDirectory func Signed-off-by: Dwi Siswanto <git@dw1.io> * refactor: use path-aware filesystem containment checks Several filesystem trust boundaries relied on lexical prefix checks to decide whether a path fell under an allowed directory. That let sibling paths be treated as if they were children of trusted directories. Replace those checks with canonical path containment checks for helper payload loading, template archive extraction, custom template metadata, template path classification, and headless screenshot output validation. Signed-off-by: Dwi Siswanto <git@dw1.io> * adding more tests * fixing tests * adding test --------- Signed-off-by: Dwi Siswanto <git@dw1.io> Co-authored-by: Mzack9999 <mzack9999@protonmail.com>
70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
package disk
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
|
|
fileutil "github.com/projectdiscovery/utils/file"
|
|
)
|
|
|
|
// ResolvePath resolves the path to an absolute one in various ways.
|
|
//
|
|
// It checks if the filename is an absolute path, looks in the current directory
|
|
// or checking the nuclei templates directory. If a second path is given,
|
|
// it also tries to find paths relative to that second path.
|
|
func (c *DiskCatalog) ResolvePath(templateName, second string) (string, error) {
|
|
if filepath.IsAbs(templateName) {
|
|
return templateName, nil
|
|
}
|
|
if c.templatesFS != nil {
|
|
if potentialPath, err := c.tryResolve(templateName); err != errNoValidCombination {
|
|
return potentialPath, nil
|
|
}
|
|
}
|
|
if second != "" {
|
|
secondBasePath := filepath.Join(filepath.Dir(second), templateName)
|
|
if potentialPath, err := c.tryResolve(secondBasePath); err != errNoValidCombination {
|
|
return potentialPath, nil
|
|
}
|
|
}
|
|
|
|
if c.templatesFS == nil {
|
|
curDirectory, err := os.Getwd()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
templatePath := filepath.Join(curDirectory, templateName)
|
|
if potentialPath, err := c.tryResolve(templatePath); err != errNoValidCombination {
|
|
return potentialPath, nil
|
|
}
|
|
}
|
|
|
|
templatePath := filepath.Join(config.DefaultConfig.GetTemplateDir(), templateName)
|
|
if potentialPath, err := c.tryResolve(templatePath); err != errNoValidCombination {
|
|
return potentialPath, nil
|
|
}
|
|
|
|
return "", fmt.Errorf("no such path found: %s", templateName)
|
|
}
|
|
|
|
var errNoValidCombination = errors.New("no valid combination found")
|
|
|
|
// tryResolve attempts to load locate the target by iterating across all the folders tree
|
|
func (c *DiskCatalog) tryResolve(fullPath string) (string, error) {
|
|
if c.templatesFS == nil {
|
|
if fileutil.FileOrFolderExists(fullPath) {
|
|
return fullPath, nil
|
|
}
|
|
} else {
|
|
if _, err := fs.Stat(c.templatesFS, fullPath); err == nil {
|
|
return fullPath, nil
|
|
}
|
|
}
|
|
return "", errNoValidCombination
|
|
}
|