mirror of
https://github.com/lunchcat/sif.git
synced 2026-08-02 08:47:38 -07:00
rolls the (c) 2022-2025 banner to 2022-2026 across all go files, the startup banner in sif.go, and the header-check workflow's expected format. comment-only, nothing else changes.
112 lines
3.0 KiB
Go
112 lines
3.0 KiB
Go
/*
|
|
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
|
|
: :
|
|
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
|
|
: ▄█ █ █▀ · BSD 3-Clause License :
|
|
: :
|
|
: (c) 2022-2026 vmfunc, xyzeva, :
|
|
: lunchcat alumni & contributors :
|
|
: :
|
|
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
|
|
*/
|
|
|
|
package templates
|
|
|
|
import (
|
|
"archive/tar"
|
|
"compress/gzip"
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/charmbracelet/log"
|
|
)
|
|
|
|
const (
|
|
archive = "https://github.com/projectdiscovery/nuclei-templates/archive/refs/tags/v%s.tar.gz"
|
|
ref = "9.6.2"
|
|
)
|
|
|
|
func Install(logger *log.Logger) error {
|
|
// Check if already exists
|
|
if _, err := os.Stat("nuclei-templates"); err == nil {
|
|
return nil
|
|
}
|
|
|
|
logger.Infof("nuclei-templates directory not found. Installing...")
|
|
|
|
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, fmt.Sprintf(archive, ref), http.NoBody)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
tarball, err := gzip.NewReader(resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if cerr := tarball.Close(); cerr != nil {
|
|
logger.Warnf("closing gzip reader: %v", cerr)
|
|
}
|
|
}()
|
|
|
|
data := tar.NewReader(tarball)
|
|
|
|
dest, err := os.Getwd()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cleanDest := filepath.Clean(dest)
|
|
|
|
for {
|
|
header, err := data.Next()
|
|
if errors.Is(err, io.EOF) {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// guard against path traversal ("Zip Slip"): the resolved path must
|
|
// stay within the extraction directory before any filesystem op.
|
|
target := filepath.Join(cleanDest, header.Name)
|
|
if !strings.HasPrefix(target, cleanDest+string(os.PathSeparator)) {
|
|
return fmt.Errorf("invalid archive entry %q: escapes extraction directory", header.Name)
|
|
}
|
|
|
|
switch header.Typeflag {
|
|
case tar.TypeDir:
|
|
if err := os.Mkdir(target, 0o750); err != nil {
|
|
return err
|
|
}
|
|
case tar.TypeReg:
|
|
file, err := os.Create(target)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if _, err := io.Copy(file, data); err != nil {
|
|
file.Close()
|
|
return err
|
|
}
|
|
file.Close()
|
|
}
|
|
}
|
|
|
|
if err := os.Rename(fmt.Sprintf("nuclei-templates-%s", ref), "nuclei-templates"); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|