feat: implement safe HTTP client and URL validation for secure downloads

This commit is contained in:
MengMengCode
2026-07-26 04:19:38 +08:00
parent 37b16b83a5
commit 5474991a6d
10 changed files with 404 additions and 78 deletions
+3 -16
View File
@@ -7,13 +7,14 @@ import (
"encoding/hex"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
"time"
"clicd/internal/safehttp"
)
type CustomImageDownloadProgress struct {
@@ -91,21 +92,7 @@ func DownloadCustomImageWithProgress(ctx context.Context, template Template, pro
}
func downloadCustomRootfs(ctx context.Context, sourceURL, target string, progress CustomImageDownloadProgressFunc) error {
client := http.Client{
Timeout: 30 * time.Minute,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) >= 10 {
return fmt.Errorf("too many redirects")
}
return nil
},
}
request, err := http.NewRequestWithContext(ctx, http.MethodGet, sourceURL, nil)
if err != nil {
return err
}
request.Header.Set("User-Agent", "CLICD/1.0 LXC image downloader")
response, err := client.Do(request)
response, err := safehttp.Get(ctx, sourceURL, "CLICD/1.0 LXC image downloader", 30*time.Minute)
if err != nil {
return err
}
+1 -1
View File
@@ -1591,7 +1591,7 @@ func (m *Manager) applyIPv6Config(lxcName string, ipv6s ...string) error {
return fmt.Errorf("failed to read container config: %v", err)
}
lines := strings.Split(string(data), "\n")
next := make([]string, 0, len(lines)+4)
next := make([]string, 0, len(lines))
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if strings.Contains(trimmed, "# clicd managed: public IPv6") ||
+1 -1
View File
@@ -410,7 +410,7 @@ func (cfg *ContainerConfig) NormalizeCreateNATMappings() error {
}
func (cfg ContainerConfig) RequestedNATHostPorts() []int {
ports := make([]int, 0, len(cfg.NATPortMappings)+1)
ports := make([]int, 0, len(cfg.NATPortMappings))
if cfg.ManagementPort > 0 {
ports = append(ports, cfg.ManagementPort)
}
+1 -1
View File
@@ -837,7 +837,7 @@ func createNATReservationOwner(name string) string {
}
func createNATReservationMappings(cfg ContainerConfig, managementPort int) []config.PortMapping {
reservations := make([]config.PortMapping, 0, len(cfg.NATPortMappings)+1)
reservations := make([]config.PortMapping, 0, len(cfg.NATPortMappings))
if managementPort > 0 {
reservations = append(reservations, config.PortMapping{HostPort: managementPort, Protocol: "tcp"})
}