fix(security): SSRF log injection and folder permissions

This commit is contained in:
2026-05-17 14:13:38 +02:00
parent 72a813cfc1
commit 94fa9de6a7
5 changed files with 41 additions and 14 deletions
+2 -2
View File
@@ -384,7 +384,7 @@ func CreateProduct(c *gin.Context) {
// ✅ CRÉER LE DOSSIER DE MANIÈRE SÉCURISÉE
destFolder := filepath.Join("uploads", mediaType+"s")
if err := os.MkdirAll(destFolder, 0755); err != nil {
if err := os.MkdirAll(destFolder, 0750); err != nil {
log.Printf("❌ [CreateProduct] Erreur création dossier: %v", err)
rollbackFiles(savedFiles)
database.DeleteProduct(product.ID)
@@ -848,7 +848,7 @@ func UploadMedia(c *gin.Context) {
// ✅ CRÉER LE DOSSIER
destFolder := filepath.Join("uploads", fileType+"s")
if err := os.MkdirAll(destFolder, 0755); err != nil {
if err := os.MkdirAll(destFolder, 0750); err != nil {
log.Printf("❌ [UploadMedia] Erreur création dossier: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur création dossier"})
return
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"log"
"net/http"
"os"
"strings"
"github.com/gin-gonic/gin"
)
@@ -89,7 +90,7 @@ func UpdateSettings(c *gin.Context) {
if err := services.TelegramBot.SetWebhook(webhookURL); err != nil {
log.Printf("⚠️ [SETTINGS] Erreur enregistrement webhook Telegram: %v", err)
} else {
log.Printf("✅ [SETTINGS] Webhook Telegram enregistré: %s", webhookURL)
log.Printf("✅ [SETTINGS] Webhook Telegram enregistré: %s", strings.NewReplacer("\n", "", "\r", "").Replace(webhookURL))
}
}
}
+17 -5
View File
@@ -274,13 +274,25 @@ func CalculateETAWithTomTom(from, to Coordinates) (int, float64, error) {
}
// API TomTom Routing: Calculate Route avec trafic
apiURL := fmt.Sprintf(
"https://api.tomtom.com/routing/1/calculateRoute/%f,%f:%f,%f/json?key=%s&traffic=true&travelMode=car",
from.Latitude, from.Longitude, to.Latitude, to.Longitude, apiKey,
)
u := &url.URL{
Scheme: "https",
Host: "api.tomtom.com",
Path: fmt.Sprintf("/routing/1/calculateRoute/%f,%f:%f,%f/json", from.Latitude, from.Longitude, to.Latitude, to.Longitude),
}
q := url.Values{}
q.Set("key", apiKey)
q.Set("traffic", "true")
q.Set("travelMode", "car")
u.RawQuery = q.Encode()
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
if err != nil {
distance := CalculateDistance(from, to)
return CalculateETA(distance), distance, nil
}
client := &http.Client{Timeout: 8 * time.Second}
resp, err := client.Get(apiURL)
resp, err := client.Do(req)
if err != nil {
// Fallback sur calcul local en cas d'erreur réseau
distance := CalculateDistance(from, to)
+17 -5
View File
@@ -11,6 +11,7 @@ import (
"io"
"log"
"net/http"
"net/url"
"os"
"time"
)
@@ -21,13 +22,24 @@ func GetETAWithTraffic(from, to Coordinates) (etaMinutes int, distanceKm float64
return 0, 0, fmt.Errorf("TOMTOM_API_KEY non configurée")
}
url := fmt.Sprintf(
"https://api.tomtom.com/routing/1/calculateRoute/%f,%f:%f,%f/json?key=%s&traffic=true&travelMode=car",
from.Latitude, from.Longitude, to.Latitude, to.Longitude, apiKey,
)
u := &url.URL{
Scheme: "https",
Host: "api.tomtom.com",
Path: fmt.Sprintf("/routing/1/calculateRoute/%f,%f:%f,%f/json", from.Latitude, from.Longitude, to.Latitude, to.Longitude),
}
q := url.Values{}
q.Set("key", apiKey)
q.Set("traffic", "true")
q.Set("travelMode", "car")
u.RawQuery = q.Encode()
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
if err != nil {
return 0, 0, fmt.Errorf("erreur construction requête TomTom: %w", err)
}
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Get(url)
resp, err := client.Do(req)
if err != nil {
return 0, 0, fmt.Errorf("erreur requête TomTom: %w", err)
}
+3 -1
View File
@@ -68,7 +68,9 @@ func AutoAssignWorker(database *db.Database) {
nextCommand.CommandID, err)
} else {
log.Printf("✅ Commande %d auto-assignée", nextCommand.CommandID)
database.RemoveCommandFromQueue(nextCommand.CommandID)
if err := database.RemoveCommandFromQueue(nextCommand.CommandID); err != nil {
log.Printf("⚠️ Impossible de retirer la commande %d de la queue: %v", nextCommand.CommandID, err)
}
}
}
}